generated from muhtadeetaron/nextjs-template
fix(api): fix api endpoint logic #3
This commit is contained in:
@ -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 */}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -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
16
types/auth.d.ts
vendored
@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user