generated from codersforcauses/django-nextjs-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin' into fix/backend-api-issues
- Loading branch information
Showing
11 changed files
with
375 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 12 additions & 1 deletion
13
client/src/components/ui/task-top-bar.tsx → ...src/components/ui/poster/task-top-bar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { useRouter } from "next/router"; | ||
import { useEffect, useState } from "react"; | ||
|
||
import { axiosInstance } from "@/lib/api"; | ||
|
||
function useFetchData(apiEndpoint: string, trigger: boolean) { | ||
const [data, setData] = useState<any>(null); | ||
const [loading, setLoading] = useState(true); | ||
const [error, setError] = useState<string>(""); | ||
|
||
useEffect(() => { | ||
if (!trigger) return; | ||
const fetchData = async () => { | ||
try { | ||
const response = await axiosInstance.get(apiEndpoint); | ||
setData(response.data); | ||
} catch (error: unknown) { | ||
if (error instanceof Error) { | ||
setError(error.message); | ||
} else { | ||
setError("An unexpected error occurred"); | ||
} | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
fetchData(); | ||
}, [apiEndpoint]); | ||
|
||
return { data, loading, error }; | ||
} | ||
|
||
export default useFetchData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import jwt from "jsonwebtoken"; | ||
import { useRouter } from "next/router"; | ||
import { useEffect, useState } from "react"; | ||
|
||
import useFetchData from "@/hooks/use-fetch-data"; | ||
import { axiosInstance } from "@/lib/api"; | ||
|
||
import { | ||
AboutInfoIcon, | ||
EditIcon, | ||
HelpCircleIcon, | ||
LogoutIcon, | ||
PaymentIcon, | ||
SettingsIcon, | ||
} from "../../../components/ui/icons"; | ||
import { PersonImg } from "../../../components/ui/person-detail"; | ||
import ProfileTag from "../../../components/ui/profile-tags"; | ||
|
||
const ProfilePage: React.FC = () => { | ||
const router = useRouter(); | ||
const { posterid } = router.query; | ||
const queryReady = typeof posterid === "string"; | ||
|
||
const { | ||
data: user, | ||
loading: userLoading, | ||
error: userError, | ||
} = useFetchData(`/app/profiles/${posterid}/`, queryReady); | ||
if (userLoading) return <div>Loading...</div>; | ||
if (userError) return <div>Error: {userError}</div>; | ||
const token = localStorage.getItem("token"); | ||
if (!token) throw new Error("No token found"); | ||
const decoded = jwt.decode(token) as { email: string }; | ||
const email = decoded.email; | ||
// img src needs to change to user.avatar_url later | ||
return ( | ||
<div className="m-0"> | ||
<div className="mt-20 flex flex-col items-center"> | ||
<PersonImg personImg="" size={120} /> | ||
<p className="mt-4 text-t3 font-semibold text-penni-text-regular-light-mode"> | ||
{user.full_name} | ||
</p> | ||
<p className="text-sh font-normal text-penni-text-secondary-light-mode"> | ||
{email} | ||
</p> | ||
</div> | ||
<div className="mt-6"> | ||
<ProfileTag | ||
icon={EditIcon} | ||
title="Edit Profile" | ||
description="Update your personal information" | ||
link="" | ||
/> | ||
<ProfileTag | ||
icon={PaymentIcon} | ||
title="Payments" | ||
description="To make payments" | ||
link="" | ||
/> | ||
<ProfileTag | ||
icon={SettingsIcon} | ||
title="Account Settings" | ||
description="Lorem ipsum dolor sit amet." | ||
link="" | ||
/> | ||
<ProfileTag | ||
icon={AboutInfoIcon} | ||
title="About" | ||
description="Lorem ipsum dolor sit amet." | ||
link="" | ||
/> | ||
<ProfileTag | ||
icon={HelpCircleIcon} | ||
title="Help Centre" | ||
description="Lorem ipsum dolor sit amet." | ||
link="" | ||
/> | ||
|
||
<ProfileTag | ||
icon={LogoutIcon} | ||
title="Logout" | ||
description="" | ||
nestedContent="" | ||
/> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ProfilePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 61 additions & 25 deletions
86
client/src/pages/poster/tasks/[taskid]/[bidderid]/bid-details.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,71 @@ | ||
import { useRouter } from "next/router"; | ||
import React from "react"; | ||
import { useEffect, useState } from "react"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import Header from "@/components/ui/header"; | ||
import PersonDetail from "@/components/ui/person-detail"; | ||
import useFetchData from "@/hooks/use-fetch-data"; | ||
import { axiosInstance } from "@/lib/api"; | ||
|
||
export default function BidDetail() { | ||
const router = useRouter(); | ||
if (router.query.bidder === undefined || router.query.taskid === undefined) { | ||
return <>Loading...</>; | ||
} | ||
const bidder = JSON.parse(String(router.query.bidder)); | ||
const taskid = String(router.query.taskid); | ||
function OnClick() { | ||
// axios.post to api | ||
router.push(`/poster/task/${taskid}/${bidder.id}/payment`); | ||
} | ||
return ( | ||
<div className="w-screenbg-green-400 h-lvh"> | ||
<Header title="Bid Details" className="sticky top-0 z-10 w-full" /> | ||
<div className="absolute flex h-5/6 w-full flex-col p-4"> | ||
<PersonDetail personName={bidder.name} personImg={bidder.profile} /> | ||
<p className="mt-4 self-center">{bidder.bio}</p> | ||
<Button | ||
size="penni" | ||
onClick={OnClick} | ||
className="absolute -bottom-4 w-10/12 self-center" | ||
> | ||
Hire for ${bidder.price} | ||
</Button> | ||
const { taskid, bidderid } = router.query; | ||
// Check if taskid and bidderid are strings | ||
const queryReady = typeof taskid === "string" && typeof bidderid === "string"; | ||
|
||
// Fetch bids of this task | ||
const { | ||
data: bids, | ||
loading: bidsLoading, | ||
error: bidsError, | ||
} = useFetchData(`/app/tasks/${taskid}/bids/`, queryReady); | ||
// Fetch profiles of all users | ||
const { | ||
data: profiles, | ||
loading: profilesLoading, | ||
error: profilesError, | ||
} = useFetchData(`/app/profiles/`, true); | ||
if (bidsLoading || profilesLoading) return <div>Loading...</div>; | ||
|
||
if (bidsError) return <div>Error: {bidsError}</div>; | ||
if (profilesError) return <div>Error: {profilesError}</div>; | ||
const OnClick = () => { | ||
router.push(`/poster/payment`); //link to payment detail page | ||
}; | ||
|
||
if (typeof bidderid != "string") { | ||
return <div>Loading...</div>; | ||
} else { | ||
const bidInfo = bids.data.filter( | ||
(bid: any) => bid.bidder_id === parseInt(bidderid), | ||
)[0]; | ||
// filter profile of this bidder | ||
const bidderProfile = profiles.filter( | ||
(profile: any) => profile.user_id === parseInt(bidderid), | ||
)[0]; | ||
|
||
bidInfo["avatar_url"] = ""; // source of img has error. needs to change to bidderProfile.avatar_url later | ||
bidInfo["full_name"] = bidderProfile.full_name; | ||
bidInfo["bio"] = bidderProfile.bio; | ||
|
||
return ( | ||
<div className="w-screenbg-green-400 h-lvh"> | ||
<Header title="Bid Details" className="sticky top-0 z-10 w-full" /> | ||
<div className="absolute flex h-5/6 w-full flex-col border-t border-penni-grey-border-light-mode p-4"> | ||
<PersonDetail | ||
personName={bidInfo.full_name} | ||
personImg={bidInfo.avatar_url} | ||
/> | ||
<p className="mt-4">{bidInfo.bio}</p> | ||
<Button | ||
size="penni" | ||
onClick={OnClick} | ||
className="absolute -bottom-4 w-10/12 self-center" | ||
> | ||
Hire for {bidInfo.price} | ||
</Button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
); | ||
} | ||
} |
Oops, something went wrong.