generated from muhtadeetaron/nextjs-template
fix(api): fix api endpoint logic #1
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -39,3 +39,5 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
.vercel
|
||||||
|
|||||||
@ -22,13 +22,17 @@ export default function RegisterPage() {
|
|||||||
const { setToken } = useAuth();
|
const { setToken } = useAuth();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [form, setForm] = useState<RegisterForm>({
|
const [form, setForm] = useState<RegisterForm>({
|
||||||
name: "",
|
full_name: "",
|
||||||
institution: "",
|
username: "",
|
||||||
sscRoll: "",
|
|
||||||
hscRoll: "",
|
|
||||||
email: "",
|
email: "",
|
||||||
phone: "",
|
|
||||||
password: "",
|
password: "",
|
||||||
|
phone_number: "",
|
||||||
|
ssc_roll: 0,
|
||||||
|
ssc_board: "",
|
||||||
|
hsc_roll: 0,
|
||||||
|
hsc_board: "",
|
||||||
|
college: "",
|
||||||
|
preparation_unit: "",
|
||||||
});
|
});
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
@ -44,8 +48,8 @@ export default function RegisterPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const validateForm = () => {
|
const validateForm = () => {
|
||||||
const { sscRoll, hscRoll, password } = form;
|
const { ssc_roll, hsc_roll, password } = form;
|
||||||
if (sscRoll === hscRoll) {
|
if (ssc_roll === hsc_roll) {
|
||||||
return "SSC Roll and HSC Roll must be unique.";
|
return "SSC Roll and HSC Roll must be unique.";
|
||||||
}
|
}
|
||||||
const passwordRegex =
|
const passwordRegex =
|
||||||
@ -93,11 +97,11 @@ export default function RegisterPage() {
|
|||||||
return (
|
return (
|
||||||
<BackgroundWrapper>
|
<BackgroundWrapper>
|
||||||
<div className="min-h-screen flex flex-col items-center justify-center px-4 py-10">
|
<div className="min-h-screen flex flex-col items-center justify-center px-4 py-10">
|
||||||
<div className="w-full max-w-md space-y-6">
|
<div className="w-full space-y-6">
|
||||||
<div className="w-full aspect-[368/89] mx-auto">
|
<div className="w-full aspect-[368/89] mx-auto">
|
||||||
<Image
|
<Image
|
||||||
src="/images/logo/logo.png"
|
src="/images/logo/logo.png"
|
||||||
alt="Logo"
|
alt="logo"
|
||||||
width={368}
|
width={368}
|
||||||
height={89}
|
height={89}
|
||||||
className="w-full h-auto"
|
className="w-full h-auto"
|
||||||
@ -106,48 +110,34 @@ export default function RegisterPage() {
|
|||||||
|
|
||||||
<div className="space-y-10">
|
<div className="space-y-10">
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
|
<h1 className="text-2xl font-semibold">Personal Info</h1>
|
||||||
<FormField
|
<FormField
|
||||||
title="Full name"
|
title="Full name"
|
||||||
value={form.name}
|
value={form.full_name}
|
||||||
handleChangeText={(value) => setForm({ ...form, name: value })}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
title="Institution"
|
|
||||||
value={form.institution}
|
|
||||||
handleChangeText={(value) =>
|
handleChangeText={(value) =>
|
||||||
setForm({ ...form, institution: value })
|
setForm({ ...form, full_name: value })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
title="SSC Roll No."
|
title="User name"
|
||||||
value={form.sscRoll}
|
value={form.username}
|
||||||
handleChangeText={(value) =>
|
handleChangeText={(value) =>
|
||||||
setForm({ ...form, sscRoll: value })
|
setForm({ ...form, username: value })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
title="HSC Roll No."
|
title="Phone Number"
|
||||||
value={form.hscRoll}
|
value={form.phone_number}
|
||||||
handleChangeText={(value) =>
|
handleChangeText={(value) =>
|
||||||
setForm({ ...form, hscRoll: value })
|
setForm({ ...form, phone_number: value })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
title="Email Address"
|
title="Email Address"
|
||||||
value={form.email}
|
value={form.email}
|
||||||
handleChangeText={(value) => setForm({ ...form, email: value })}
|
handleChangeText={(value) => setForm({ ...form, email: value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
|
||||||
title="Phone Number"
|
|
||||||
value={form.phone}
|
|
||||||
handleChangeText={(value) => setForm({ ...form, phone: value })}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
title="Password"
|
title="Password"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
@ -156,6 +146,58 @@ export default function RegisterPage() {
|
|||||||
}
|
}
|
||||||
placeholder={undefined}
|
placeholder={undefined}
|
||||||
/>
|
/>
|
||||||
|
<h1 className="text-2xl font-semibold">Educational Background</h1>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
title="College"
|
||||||
|
value={form.college}
|
||||||
|
handleChangeText={(value) =>
|
||||||
|
setForm({ ...form, college: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
title="Preparation Unit"
|
||||||
|
value={form.preparation_unit}
|
||||||
|
handleChangeText={(value) =>
|
||||||
|
setForm({ ...form, preparation_unit: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<div className="w-full flex gap-4">
|
||||||
|
<FormField
|
||||||
|
title="SSC Board"
|
||||||
|
value={form.ssc_board}
|
||||||
|
handleChangeText={(value) =>
|
||||||
|
setForm({ ...form, ssc_board: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
title="SSC Roll No."
|
||||||
|
value={form.ssc_roll}
|
||||||
|
handleChangeText={(value: string) =>
|
||||||
|
setForm({ ...form, ssc_roll: Number(value) })
|
||||||
|
}
|
||||||
|
className="max-w-26"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full flex gap-4">
|
||||||
|
<FormField
|
||||||
|
title="HSC Board"
|
||||||
|
value={form.hsc_board}
|
||||||
|
handleChangeText={(value) =>
|
||||||
|
setForm({ ...form, hsc_board: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
title="HSC Roll No."
|
||||||
|
value={form.hsc_roll}
|
||||||
|
handleChangeText={(value: string) =>
|
||||||
|
setForm({ ...form, hsc_roll: Number(value) })
|
||||||
|
}
|
||||||
|
className="max-w-26"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{error && <DestructibleAlert text={error} />}
|
{error && <DestructibleAlert text={error} />}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Suspense, useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import DestructibleAlert from "@/components/DestructibleAlert";
|
import DestructibleAlert from "@/components/DestructibleAlert";
|
||||||
import BackgroundWrapper from "@/components/BackgroundWrapper";
|
import BackgroundWrapper from "@/components/BackgroundWrapper";
|
||||||
@ -14,8 +14,7 @@ interface Mock {
|
|||||||
title: string;
|
title: string;
|
||||||
rating: number;
|
rating: number;
|
||||||
}
|
}
|
||||||
|
export default function PaperScreen() {
|
||||||
function PaperPageContent() {
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const name = searchParams.get("name") || "";
|
const name = searchParams.get("name") || "";
|
||||||
@ -23,6 +22,7 @@ function PaperPageContent() {
|
|||||||
const [questions, setQuestions] = useState<Mock[] | null>(null);
|
const [questions, setQuestions] = useState<Mock[] | null>(null);
|
||||||
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
||||||
const [refreshing, setRefreshing] = useState<boolean>(false);
|
const [refreshing, setRefreshing] = useState<boolean>(false);
|
||||||
|
const [componentKey, setComponentKey] = useState<number>(0);
|
||||||
|
|
||||||
async function fetchMocks() {
|
async function fetchMocks() {
|
||||||
try {
|
try {
|
||||||
@ -44,13 +44,17 @@ function PaperPageContent() {
|
|||||||
|
|
||||||
const onRefresh = async () => {
|
const onRefresh = async () => {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
|
|
||||||
await fetchMocks();
|
await fetchMocks();
|
||||||
|
setComponentKey((prevKey) => prevKey + 1);
|
||||||
|
setTimeout(() => {
|
||||||
|
setRefreshing(false);
|
||||||
|
}, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (errorMsg) {
|
if (errorMsg) {
|
||||||
return (
|
return (
|
||||||
<BackgroundWrapper>
|
<BackgroundWrapper>
|
||||||
<div className="min-h-screen">
|
|
||||||
<Header displayTabTitle={name} />
|
<Header displayTabTitle={name} />
|
||||||
<div className="overflow-y-auto">
|
<div className="overflow-y-auto">
|
||||||
<div className="mt-5 px-5">
|
<div className="mt-5 px-5">
|
||||||
@ -66,8 +70,6 @@ function PaperPageContent() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <CustomBackHandler fallbackRoute="unit" /> */}
|
|
||||||
</div>
|
|
||||||
</BackgroundWrapper>
|
</BackgroundWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -118,20 +120,3 @@ function PaperPageContent() {
|
|||||||
</BackgroundWrapper>
|
</BackgroundWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PaperScreen() {
|
|
||||||
<Suspense
|
|
||||||
fallback={
|
|
||||||
<BackgroundWrapper>
|
|
||||||
<div className="min-h-screen">
|
|
||||||
<div className="mx-10 mt-10 flex flex-col justify-center items-center">
|
|
||||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-900 mb-4"></div>
|
|
||||||
<p className="text-lg font-medium text-gray-900">Loading...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</BackgroundWrapper>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<PaperPageContent />
|
|
||||||
</Suspense>;
|
|
||||||
}
|
|
||||||
|
|||||||
9
capacitor.config.ts
Normal file
9
capacitor.config.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import type { CapacitorConfig } from "@capacitor/cli";
|
||||||
|
|
||||||
|
const config: CapacitorConfig = {
|
||||||
|
appId: "com.examjam.solanine",
|
||||||
|
appName: "ExamJam",
|
||||||
|
webDir: "public",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@ -1,23 +1,32 @@
|
|||||||
import React, { useState, InputHTMLAttributes } from "react";
|
import React, { useState, useId, InputHTMLAttributes } from "react";
|
||||||
|
|
||||||
interface FormFieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
interface FormFieldProps
|
||||||
|
extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "onChange"> {
|
||||||
title: string;
|
title: string;
|
||||||
|
value: string | number;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
value: string;
|
|
||||||
handleChangeText: (value: string) => void;
|
handleChangeText: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormField = ({
|
const FormField: React.FC<FormFieldProps> = ({
|
||||||
title,
|
title,
|
||||||
placeholder,
|
|
||||||
value,
|
value,
|
||||||
|
placeholder,
|
||||||
handleChangeText,
|
handleChangeText,
|
||||||
|
type,
|
||||||
...props
|
...props
|
||||||
}: FormFieldProps) => {
|
}) => {
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const isPasswordField = title.toLowerCase().includes("password");
|
const inputId = useId();
|
||||||
|
|
||||||
const inputId = `input-${title.replace(/\s+/g, "-").toLowerCase()}`;
|
const isPasswordField =
|
||||||
|
type === "password" || title.toLowerCase().includes("password");
|
||||||
|
|
||||||
|
const inputType = isPasswordField
|
||||||
|
? showPassword
|
||||||
|
? "text"
|
||||||
|
: "password"
|
||||||
|
: type || "text";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
@ -31,9 +40,10 @@ const FormField = ({
|
|||||||
<div className="h-16 px-4 bg-[#D2DFF0] rounded-3xl flex items-center justify-between">
|
<div className="h-16 px-4 bg-[#D2DFF0] rounded-3xl flex items-center justify-between">
|
||||||
<input
|
<input
|
||||||
id={inputId}
|
id={inputId}
|
||||||
type={isPasswordField && !showPassword ? "password" : "text"}
|
type={inputType}
|
||||||
value={value}
|
value={value}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder || `Enter ${title.toLowerCase()}`}
|
||||||
|
autoComplete={isPasswordField ? "current-password" : "on"}
|
||||||
onChange={(e) => handleChangeText(e.target.value)}
|
onChange={(e) => handleChangeText(e.target.value)}
|
||||||
className="flex-1 bg-transparent outline-none border-none text-blue-950 text-[16px] font-inherit"
|
className="flex-1 bg-transparent outline-none border-none text-blue-950 text-[16px] font-inherit"
|
||||||
{...props}
|
{...props}
|
||||||
@ -43,8 +53,9 @@ const FormField = ({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowPassword((prev) => !prev)}
|
onClick={() => setShowPassword((prev) => !prev)}
|
||||||
|
aria-pressed={showPassword}
|
||||||
aria-label={showPassword ? "Hide password" : "Show password"}
|
aria-label={showPassword ? "Hide password" : "Show password"}
|
||||||
className="ml-2 text-gray-600 hover:text-gray-800 focus:outline-none font-montserrat font-medium text-[16px] bg-none border-none"
|
className="ml-2 text-gray-600 hover:text-gray-800 focus:outline-none font-montserrat font-medium text-[16px]"
|
||||||
>
|
>
|
||||||
{showPassword ? "Hide" : "Show"}
|
{showPassword ? "Hide" : "Show"}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@capacitor/android": "^7.4.2",
|
||||||
"@capacitor/core": "^7.4.2",
|
"@capacitor/core": "^7.4.2",
|
||||||
"@radix-ui/react-avatar": "^1.1.10",
|
"@radix-ui/react-avatar": "^1.1.10",
|
||||||
"@radix-ui/react-label": "^2.1.7",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
|
|||||||
14
types/auth.d.ts
vendored
14
types/auth.d.ts
vendored
@ -8,13 +8,17 @@ export interface UserData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RegisterForm {
|
export interface RegisterForm {
|
||||||
name: string;
|
full_name: string;
|
||||||
institution: string;
|
username: string;
|
||||||
sscRoll: string;
|
|
||||||
hscRoll: string;
|
|
||||||
email: string;
|
email: string;
|
||||||
phone: string;
|
|
||||||
password: string;
|
password: string;
|
||||||
|
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 LoginForm {
|
export interface LoginForm {
|
||||||
|
|||||||
Reference in New Issue
Block a user