Skip to content

Profile page #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 70 additions & 10 deletions client/app/profile/[userId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,99 @@
"use client";
import BackgroundComponent from "@/components/profile/backgroundComp";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import useGetUserProfile from "@/hooks/user_data/useGetUserProfile";
import { PersonIcon } from "@radix-ui/react-icons";
import { useParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { EditIcon, Factory, CircleUser } from "lucide-react";
import {useEffect, useState} from "react";



export default function ProfilePage() {
const userId = useParams().userId.toString();

const router = useRouter();
const { userData } = useGetUserProfile(userId);
const { user, stsDetails, landfillDetails, getUserDetails} = useGetUserProfile(); // Destructure user and getUserDetails
const [role, setRole] = useState<string>("Role Name");
const RolePlace = 'Station';

useEffect(() => {
getUserDetails();
setRole(user.roleName);

}, []);


return (
<div className="w-screen h-screen flex flex-col items-center justify-center gap-6">
<div className="w-screen h-screen ">
<BackgroundComponent />
<Button
variant="outline"
className="w-40"
className="absolute top-[40px] m-24 mx-40"
onClick={() => router.push("/dashboard")}
>
Back to Dashboard
</Button>
<div className="border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground p-10 rounded-xl flex flex-col justify-center items-center gap-8">
<div className="absolute top-[20px] right-[100px] text-3xl text-white flex">
{user.roleName}<CircleUser className="mx-2 h-8 w-8" />
</div>
<div className="absolute top-[85px] w-4/5 mx-40 my-24 h-4/6 flex ">
<div className="h-full w-96 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground p-10 rounded-xl flex flex-col justify-center items-center gap-8">
<Avatar className="w-24 h-24">
<AvatarFallback>
<PersonIcon className="w-3/6 h-3/6" />
</AvatarFallback>
</Avatar>
<h1 className="font-bold text-xl">Profile Page</h1>
<div className="flex flex-col justify-center items-center">
<h1><span className="font-bold">ID: </span>{userId}</h1>
<p><span className="font-bold">Email: </span>{userData.email}</p>
<p><span className="font-bold">Role: </span>{userData.role}</p>
<p><span className="font-bold">Name: </span>{userData.name}</p>
<p><span className="font-bold">Assigned Area: </span>{userData.assignedArea}</p>
<h1><span className="font-bold">ID: </span></h1>
<p><span className="font-bold">Email: </span>{user.email}</p>
<p><span className="font-bold">Role: </span>{user.roleName}</p>
<p><span className="font-bold">Name: </span>{user.profileName}</p>
<p><span className="font-bold">Role Description: </span>{user.roleDescription}</p>
</div>
<Button
variant="outline"
className="w-24"
onClick={() => router.push("/dashboard")}
><EditIcon className="h-4 w-4" />
Edit
</Button>
</div>


<div className="h-full w-4/6 ml-32 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground p-10 rounded-xl flex flex-col justify-center items-center gap-8">

<Factory className="w-24 h-24" />

{user?.roleName === 'STS_MANAGER' && <div>
<div className="font-bold text-2xl mb-4">STS Details</div>
<p><span className="font-bold">Id: </span>{stsDetails.stsId}</p>
<p><span className="font-bold">STS Name: </span>{stsDetails.stsName}</p>
<p><span className="font-bold">Ward Number: </span>{stsDetails.stsWardNumber}</p>
<p><span className="font-bold">Capacity: </span>{stsDetails.stsCapacity}</p>
<p><span className="font-bold">Current Total Waste: </span>{stsDetails.stsCurrentTotalWaste}</p>
<p><span className="font-bold">Coordinate: </span>{stsDetails.stsLatitude}, {stsDetails.stsLongitude}</p>


</div>

}
{user?.roleName === 'LAND_MANAGER' && <div>
<div className="font-bold text-2xl my-4">Landfill Details</div>
<p><span className="font-bold">ID: </span>{landfillDetails.landfillId}</p>
<p><span className="font-bold">Landfill Name: </span>{landfillDetails.landFillName}</p>
<p><span className="font-bold">Capacity: </span>{landfillDetails.landFillCapacity}</p>
<p><span className="font-bold">Current Total Waste: </span>{landfillDetails.landFillCurrentWaste}</p>
<p><span className="font-bold">Coordinate: </span>{landfillDetails.landfillLatitude}, {landfillDetails.landFillLongitude}</p>


</div>}
{user?.roleName !== 'STS_MANAGER' && user?.roleName !== 'LAND_MANAGER' && (
<div>Oops! Your role has not assigned yet</div>
)}
</div>
</div>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions client/components/maps/AllStsShow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import useGetAllSTS from "@/hooks/stsdata/useGetAllSTS";
import GoogleMapComponent from "@/components/maps/GoogleMap";
import * as React from "react";
import useGetUserProfile from "@/hooks/user_data/useGetUserProfile";

type StsShow = {
lat: number;
Expand All @@ -10,6 +11,7 @@ type StsShow = {

export const AllStsMapShow = () => {
const { getAllSTS, stsCoordinate, storagePercentage } = useGetAllSTS();


const staticCoordinates: StsShow[] = [
{ lat: 23.7031879, lng: 90.35564201 },
Expand All @@ -25,6 +27,7 @@ export const AllStsMapShow = () => {

React.useEffect(() => {
getAllSTS();

}, []);

return <GoogleMapComponent coordinates={stsCoordinate} dumpFills={storagePercentage} />;
Expand Down
17 changes: 17 additions & 0 deletions client/components/profile/backgroundComp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// components/BackgroundComponent.tsx
"use client";

import React from 'react';

const BackgroundComponent: React.FC = () => {
return (
<div
className="relative bg-primary top-[-150px] bg-cover bg-center mx-auto h-80 md:h-96 lg:h-380"

>

</div>
);
};

export default BackgroundComponent;
4 changes: 4 additions & 0 deletions client/data/apiRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const apiRoutes = {
edit: `${baseUrl}/landfills/`,
},
rbac: {

create: `${baseUrl}/rbac/roles`,
getByRole: `${baseUrl}/rbac/roles/get/`,
delete: `${baseUrl}/rbac/roles/delete/`,
Expand All @@ -51,4 +52,7 @@ export const apiRoutes = {
makeBill: `${baseUrl}/bills/create-from-trip/`,
search: `${baseUrl}/bills/search`,
},
profile: {
getProfile: `${baseUrl}/profile`,
}
}
182 changes: 155 additions & 27 deletions client/hooks/user_data/useGetUserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,163 @@



import { useState, useEffect } from 'react';
import axios from 'axios';
import { apiRoutes } from '@/data/apiRoutes'; // Adjust the import path
import { jwtToken } from '@/data/cookieNames'; // Adjust the import path
import { getCookie } from '@/lib/cookieFunctions'; // Adjust the import path

type User = {
id: string;
username: string;
email: string;
profileName: string;
roleName: string;
roleDescription: string;

};

export default function useGetUserProfile(userId: string) {
type STSType = {
stsId: string ;
stsName: string;
stsWardNumber: string;
stsCapacity: string;
stsCurrentTotalWaste: string;
stsLatitude: string;
stsLongitude: string;
}

const [userData, setUserData] = useState({
email: "",
role: "",
name: "",
assignedArea: "",
type LandfillType = {
landfillId: string ;
landFillName: string;
landFillCapacity: string;
landFillCurrentWaste: string;
landfillLatitude: string;
landFillLongitude: string;
}

export default function useGetUserProfile() {
const [user, setUser] = useState<User >({
id: '',
username: '',
email: '',
profileName: '',
roleName: '',
roleDescription: '',
}); // Initialize with undefined
const [stsDetails, setStsDetails] = useState<STSType >({
stsId: '',
stsName: '',
stsWardNumber: '',
stsCapacity: '',
stsCurrentTotalWaste: '',
stsLatitude: '',
stsLongitude: '',
});

useEffect(() => {
fetchUser();
}, []);

async function fetchUser() {

setUserData({
email: userId + "@gmail.com",
role: "STS Manager",
name: "Mehrajul Islam",
assignedArea: "Gulshan-1, Dhaka",
});

if (userData) {
// Call the API
const [landfillDetails, setLandfillDetails] = useState<LandfillType>({
landfillId: '',
landFillName: '',
landFillCapacity: '',
landFillCurrentWaste: '',
landfillLatitude: '',
landFillLongitude: '',
});

async function getUserDetails() {
try {
const res = await axios.get(apiRoutes.profile.getProfile, {
headers: { Authorization: `Bearer ${getCookie(jwtToken)}` },
});
console.log(res.data);
if (res.data.roleName === "STS_MANAGER" ) {
const userDetails: User = {
id: res.data.id,
username: res.data.username,
email: res.data.email,
profileName: res.data.profileName,
roleName: res.data.roleName,
roleDescription: res.data.role.description,


};

if(res.data.stsId){
const ResStsDetails: STSType = {
stsId: res.data.sts.id,
stsName: res.data.sts.name,
stsWardNumber: res.data.sts.wardNumber,
stsCapacity: res.data.sts.capacity,
stsCurrentTotalWaste: res.data.sts.currentTotalWaste,
stsLatitude: res.data.sts.latitude,
stsLongitude: res.data.sts.longitude,
}
setStsDetails(ResStsDetails);
}



setUser(userDetails);

return userData;
}

return null;
} else if(res.data.roleName === "LAND_MANAGER" ) {

const userDetails: User = {
id: res.data.id,
username: res.data.username,
email: res.data.email,
profileName: res.data.profileName,
roleName: res.data.roleName,
roleDescription: res.data.role.description,


};

if(res.data.landfillId){
const ResLandDetails: LandfillType = {

landfillId: res.data.landfill.id,
landFillName: res.data.landfill.name,
landFillCapacity: res.data.landfill.capacity,
landFillCurrentWaste: res.data.landfill.currentTotalWaste,
landfillLatitude: res.data.landfill.latitude,
landFillLongitude: res.data.landfill.longitude,
};
setLandfillDetails(ResLandDetails);

}



setUser(userDetails);


}else{
const userDetails: User = {
id: res.data.id,
username: res.data.username,
email: res.data.email,
profileName: res.data.profileName,
roleName: res.data.roleName,
roleDescription: res.data.role.description,


};
setUser(userDetails);

}



} catch (error: any) {
alert(error.message?.toString() || 'Error fetching user profile'); // Updated error message
}
}

return {userData};
}
useEffect(() => {
console.log(user);
console.log(stsDetails);
console.log(landfillDetails)
}, [user, stsDetails, landfillDetails]); // Call getUserDetails when the component mounts

return { user, stsDetails, landfillDetails, getUserDetails };
}
Binary file added client/public/profileBack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion server/src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getToken,
invalidateToken,
verifyToken,
} from "../services/token";
} from "../services/Token";
import CustomError from "../services/CustomError";
import { randomOTPGenerator, randomPasswordGenerator } from "../services/utils";
import { sendMail, sendOTPMail } from "../services/mailService";
Expand Down
4 changes: 3 additions & 1 deletion server/src/controllers/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import errorWrapper from "../middlewares/errorWrapper";
import { PrismaClient, User } from "@prisma/client";
import { Request, Response } from "express";
import CustomError from "../services/CustomError";
import { getToken, verifyToken } from "../services/token";
import { getToken, verifyToken } from "../services/Token";

const prisma = new PrismaClient();

Expand All @@ -15,6 +15,8 @@ const getUserById = errorWrapper(
},
include: {
role: true,
sts: true,
landfill: true
},
});

Expand Down
2 changes: 1 addition & 1 deletion server/src/middlewares/auth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import errorWrapper from "./errorWrapper";
import CustomError from "../services/CustomError";
import { getToken, verifyToken } from "../services/token";
import { getToken, verifyToken } from "../services/Token";

const authChecker = errorWrapper(
async (req: Request, res: Response, next: NextFunction) => {
Expand Down
Loading