fix(api): fix api endpoint logic #3

This commit is contained in:
shafin-r
2025-08-17 14:08:17 +06:00
parent ad46bf954e
commit 4f23f357e6
7 changed files with 87 additions and 69 deletions

View File

@ -144,8 +144,7 @@ const HomePage = () => {
{/* Leaderboard Section */} {/* Leaderboard Section */}
<div className={styles.leaderboardWrapper}> <div className={styles.leaderboardWrapper}>
<h2 className={styles.sectionTitle}>Leaderboard</h2> <h2 className={styles.sectionTitle}>Leaderboard</h2>
<p className="text-center text-xl">Coming Soon.</p> <div className={styles.leaderboardContainer}>
{/* <div className={styles.leaderboardContainer}>
<div className={styles.topThreeHeader}> <div className={styles.topThreeHeader}>
<span className={styles.topThreeTitle}>Top 3</span> <span className={styles.topThreeTitle}>Top 3</span>
<button <button
@ -157,7 +156,7 @@ const HomePage = () => {
</div> </div>
<div className={styles.divider}></div> <div className={styles.divider}></div>
<div className={styles.topThreeList}> <div className={styles.topThreeList}>
{boardError ? ( {/* {boardError ? (
<DestructibleAlert text={boardError} /> <DestructibleAlert text={boardError} />
) : ( ) : (
getTopThree(boardData).map((student, idx) => ( getTopThree(boardData).map((student, idx) => (
@ -174,9 +173,10 @@ const HomePage = () => {
</span> </span>
</div> </div>
)) ))
)} )} */}
<h2 className="text-center text-xl">Coming soon</h2>
</div> </div>
</div> */} </div>
</div> </div>
{/* Performance Summary Section */} {/* Performance Summary Section */}

View File

@ -20,7 +20,7 @@ const ProfilePage = () => {
const token = await getToken(); const token = await getToken();
if (!token) return; if (!token) return;
const response = await fetch(`${API_URL}/me`, { const response = await fetch(`${API_URL}/me/profile/`, {
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
@ -79,7 +79,9 @@ const ProfilePage = () => {
<div className="relative mx-10"> <div className="relative mx-10">
<Avatar className="bg-[#113768] w-32 h-32 absolute -top-20 left-1/2 transform -translate-x-1/2"> <Avatar className="bg-[#113768] w-32 h-32 absolute -top-20 left-1/2 transform -translate-x-1/2">
<AvatarFallback className="text-3xl text-white"> <AvatarFallback className="text-3xl text-white">
{userData?.name ? userData.name.charAt(0).toUpperCase() : ""} {userData?.username
? userData.username.charAt(0).toUpperCase()
: ""}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>

View File

@ -24,12 +24,18 @@ import React, { useEffect, useState } from "react";
const SettingsPage = () => { const SettingsPage = () => {
const router = useRouter(); const router = useRouter();
const [userData, setUserData] = useState<UserData>({ const [userData, setUserData] = useState<UserData>({
name: "", user_id: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
institution: "", username: "",
sscRoll: "", full_name: "",
hscRoll: "",
email: "", email: "",
phone: "", is_verified: false,
phone_number: "",
ssc_roll: 0,
ssc_board: "",
hsc_roll: 0,
hsc_board: "",
college: "",
preparation_unit: "Science",
}); });
useEffect(() => { useEffect(() => {
@ -38,7 +44,7 @@ const SettingsPage = () => {
const token = await getToken(); const token = await getToken();
if (!token) return; if (!token) return;
const response = await fetch(`${API_URL}/me`, { const response = await fetch(`${API_URL}/me/`, {
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
@ -75,13 +81,15 @@ const SettingsPage = () => {
<div className="flex gap-4 items-center"> <div className="flex gap-4 items-center">
<Avatar className="bg-[#113768] w-20 h-20"> <Avatar className="bg-[#113768] w-20 h-20">
<AvatarFallback className="text-3xl text-white"> <AvatarFallback className="text-3xl text-white">
{userData?.name {userData?.username
? userData.name.charAt(0).toUpperCase() ? userData.username.charAt(0).toUpperCase()
: ""} : ""}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
<h1 className="font-semibold text-2xl">{userData?.name}</h1> <h1 className="font-semibold text-2xl">
{userData?.full_name}
</h1>
<h3 className=" text-md">{userData?.email}</h3> <h3 className=" text-md">{userData?.email}</h3>
</div> </div>
</div> </div>

View File

@ -53,7 +53,7 @@ const Header = ({
const token = await getToken(); const token = await getToken();
if (!token) return; if (!token) return;
const response = await fetch(`${API_URL}/me`, { const response = await fetch(`${API_URL}/me/`, {
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
@ -100,11 +100,13 @@ const Header = ({
<div className={styles.profile}> <div className={styles.profile}>
<Avatar className="bg-gray-200 w-10 h-10"> <Avatar className="bg-gray-200 w-10 h-10">
<AvatarFallback className=" text-lg"> <AvatarFallback className=" text-lg">
{userData?.name ? userData.name.charAt(0).toUpperCase() : ""} {userData?.username
? userData.username.charAt(0).toUpperCase()
: ""}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<span className={styles.text}> <span className={styles.text}>
Hello, {userData?.name ? userData.name.split(" ")[0] : ""} Hello, {userData?.username ? userData.username.split(" ")[0] : ""}
</span> </span>
</div> </div>
)} )}

View File

@ -1,14 +1,6 @@
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { UserData } from "@/types/auth";
interface UserData {
name: string;
institution: string;
sscRoll: string;
hscRoll: string;
email: string;
phone: string;
}
interface ProfileManagerProps { interface ProfileManagerProps {
userData: UserData | undefined; userData: UserData | undefined;
@ -23,57 +15,63 @@ export default function ProfileManager({
}: ProfileManagerProps) { }: ProfileManagerProps) {
if (!userData) return null; if (!userData) return null;
const handleChange = (field: keyof UserData, value: string) => { const handleChange = (field: keyof UserData, value: string | number) => {
setUserData((prev) => (prev ? { ...prev, [field]: value } : prev)); setUserData((prev) => (prev ? { ...prev, [field]: value } : prev));
}; };
return ( return (
<div className="mx-auto"> <div className="mx-auto">
<div className="space-y-4"> <div className="space-y-4">
<div className="space-y-2"> {/* Full Name */}
<Label htmlFor="name" className="text-sm font-semibold text-gray-700">
Name
</Label>
<Input
id="name"
type="text"
value={userData.name}
onChange={(e) => handleChange("name", e.target.value)}
className="bg-gray-50 py-6"
readOnly={!edit}
/>
</div>
<div className="space-y-2"> <div className="space-y-2">
<Label <Label
htmlFor="institution" htmlFor="full_name"
className="text-sm font-semibold text-gray-700" className="text-sm font-semibold text-gray-700"
> >
Institution Full Name
</Label> </Label>
<Input <Input
id="institution" id="full_name"
type="text" type="text"
value={userData.institution} value={userData.full_name}
onChange={(e) => handleChange("institution", e.target.value)} onChange={(e) => handleChange("full_name", e.target.value)}
className="bg-gray-50 py-6" className="bg-gray-50 py-6"
readOnly={!edit} readOnly={!edit}
/> />
</div> </div>
{/* College */}
<div className="space-y-2">
<Label
htmlFor="college"
className="text-sm font-semibold text-gray-700"
>
College
</Label>
<Input
id="college"
type="text"
value={userData.college}
onChange={(e) => handleChange("college", e.target.value)}
className="bg-gray-50 py-6"
readOnly={!edit}
/>
</div>
{/* SSC & HSC Rolls */}
<div className="flex gap-4"> <div className="flex gap-4">
<div className="space-y-2 w-full"> <div className="space-y-2 w-full">
<Label <Label
htmlFor="sscRoll" htmlFor="ssc_roll"
className="text-sm font-semibold text-gray-700" className="text-sm font-semibold text-gray-700"
> >
SSC Roll SSC Roll
</Label> </Label>
<Input <Input
id="sscRoll" id="ssc_roll"
type="text" type="number"
value={userData.sscRoll} value={userData.ssc_roll}
onChange={(e) => handleChange("sscRoll", e.target.value)} onChange={(e) => handleChange("ssc_roll", Number(e.target.value))}
className="bg-gray-50 py-6" className="bg-gray-50 py-6"
readOnly={!edit} readOnly={!edit}
/> />
@ -81,22 +79,23 @@ export default function ProfileManager({
<div className="space-y-2 w-full"> <div className="space-y-2 w-full">
<Label <Label
htmlFor="hscRoll" htmlFor="hsc_roll"
className="text-sm font-semibold text-gray-700" className="text-sm font-semibold text-gray-700"
> >
HSC Roll HSC Roll
</Label> </Label>
<Input <Input
id="hscRoll" id="hsc_roll"
type="text" type="number"
value={userData.hscRoll} value={userData.hsc_roll}
onChange={(e) => handleChange("hscRoll", e.target.value)} onChange={(e) => handleChange("hsc_roll", Number(e.target.value))}
className="bg-gray-50 py-6" className="bg-gray-50 py-6"
readOnly={!edit} readOnly={!edit}
/> />
</div> </div>
</div> </div>
{/* Email */}
<div className="space-y-2"> <div className="space-y-2">
<Label <Label
htmlFor="email" htmlFor="email"
@ -114,18 +113,19 @@ export default function ProfileManager({
/> />
</div> </div>
{/* Phone */}
<div className="space-y-2"> <div className="space-y-2">
<Label <Label
htmlFor="phone" htmlFor="phone_number"
className="text-sm font-semibold text-gray-700" className="text-sm font-semibold text-gray-700"
> >
Phone Phone
</Label> </Label>
<Input <Input
id="phone" id="phone_number"
type="tel" type="tel"
value={userData.phone} value={userData.phone_number}
onChange={(e) => handleChange("phone", e.target.value)} onChange={(e) => handleChange("phone_number", e.target.value)}
className="bg-gray-50 py-6" className="bg-gray-50 py-6"
readOnly={!edit} readOnly={!edit}
/> />

View File

@ -28,7 +28,7 @@ export const login = async (
form: LoginForm, form: LoginForm,
setToken: SetTokenFn setToken: SetTokenFn
): Promise<void> => { ): Promise<void> => {
const response = await fetch(`${API_URL}/auth/login`, { const response = await fetch(`${API_URL}/auth/login/`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -50,7 +50,7 @@ export const register = async (
form: RegisterForm, form: RegisterForm,
setToken: SetTokenFn setToken: SetTokenFn
): Promise<void> => { ): Promise<void> => {
const response = await fetch(`${API_URL}/auth/register`, { const response = await fetch(`${API_URL}/auth/register/`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",

16
types/auth.d.ts vendored
View File

@ -1,10 +1,16 @@
export interface UserData { export interface UserData {
name: string; user_id: string;
institution: string; username: string;
sscRoll: string; full_name: string;
hscRoll: string;
email: string; email: string;
phone: string; is_verified: boolean;
phone_number: string;
ssc_roll: number;
ssc_board: string;
hsc_roll: number;
hsc_board: string;
college: string;
preparation_unit: "Science" | "Arts" | "Commerce" | string;
} }
export interface RegisterForm { export interface RegisterForm {