generated from muhtadeetaron/nextjs-template
fix(ts): refactor codebase for capacitor setup
This commit is contained in:
69
lib/auth.ts
69
lib/auth.ts
@ -1,20 +1,37 @@
|
||||
export const API_URL = "https://examjam-api.pptx704.com";
|
||||
|
||||
// Cookie utility functions
|
||||
const setCookie = (name, value, days = 7) => {
|
||||
// Cookie utility function
|
||||
const setCookie = (name: string, value: string | null, days: number = 7) => {
|
||||
if (typeof document === "undefined") return;
|
||||
|
||||
if (value === null) {
|
||||
// Delete cookie by setting expiration to past date
|
||||
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Strict; Secure`;
|
||||
} else {
|
||||
const expires = new Date();
|
||||
expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/; SameSite=Strict; Secure`;
|
||||
document.cookie = `${name}=${encodeURIComponent(
|
||||
value
|
||||
)}; expires=${expires.toUTCString()}; path=/; SameSite=Strict; Secure`;
|
||||
}
|
||||
};
|
||||
|
||||
export const login = async (form, setToken) => {
|
||||
interface AuthForm {
|
||||
email: string;
|
||||
password: string;
|
||||
[key: string]: any; // for flexibility
|
||||
}
|
||||
|
||||
type SetTokenFn = (token: string) => void;
|
||||
|
||||
// Optional: Create a custom error type to carry extra data
|
||||
interface APIError extends Error {
|
||||
response?: any;
|
||||
}
|
||||
|
||||
export const login = async (
|
||||
form: AuthForm,
|
||||
setToken: SetTokenFn
|
||||
): Promise<void> => {
|
||||
const response = await fetch(`${API_URL}/auth/login`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@ -29,27 +46,14 @@ export const login = async (form, setToken) => {
|
||||
throw new Error(data.message || "Login failed");
|
||||
}
|
||||
|
||||
// Save the token to cookies instead of secure storage
|
||||
setCookie("authToken", data.token);
|
||||
setToken(data.token); // Update the token in context
|
||||
setToken(data.token);
|
||||
};
|
||||
|
||||
const handleError = (error) => {
|
||||
// Check if error has a "detail" property
|
||||
if (error?.detail) {
|
||||
// Match the field causing the issue
|
||||
const match = error.detail.match(/Key \((.*?)\)=\((.*?)\)/);
|
||||
|
||||
if (match) {
|
||||
const field = match[1]; // The field name, e.g., "phone"
|
||||
const value = match[2]; // The duplicate value, e.g., "0987654321"
|
||||
return `The ${field} already exists. Please use a different value.`;
|
||||
}
|
||||
}
|
||||
return "An unexpected error occurred. Please try again.";
|
||||
};
|
||||
|
||||
export const register = async (form, setToken) => {
|
||||
export const register = async (
|
||||
form: AuthForm,
|
||||
setToken: SetTokenFn
|
||||
): Promise<void> => {
|
||||
const response = await fetch(`${API_URL}/auth/register`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@ -58,22 +62,19 @@ export const register = async (form, setToken) => {
|
||||
body: JSON.stringify(form),
|
||||
});
|
||||
|
||||
const data = await response.json(); // Parse the response JSON
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
// Instead of throwing a string, include full error data for debugging
|
||||
const error = new Error(data?.detail || "Registration failed");
|
||||
error.response = data; // Attach the full response for later use
|
||||
const error: APIError = new Error(data?.detail || "Registration failed");
|
||||
error.response = data;
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Save the token to cookies instead of secure storage
|
||||
setCookie("authToken", data.token);
|
||||
setToken(data.token); // Update the token in context
|
||||
setToken(data.token);
|
||||
};
|
||||
|
||||
// Additional utility function to get token from cookies (if needed elsewhere)
|
||||
export const getTokenFromCookie = () => {
|
||||
export const getTokenFromCookie = (): string | null => {
|
||||
if (typeof document === "undefined") return null;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
@ -84,17 +85,15 @@ export const getTokenFromCookie = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
// Utility function to clear auth token (for logout)
|
||||
export const clearAuthToken = () => {
|
||||
export const clearAuthToken = (): void => {
|
||||
setCookie("authToken", null);
|
||||
};
|
||||
|
||||
export const getToken = async () => {
|
||||
export const getToken = async (): Promise<string | null> => {
|
||||
if (typeof window === "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Extract authToken from cookies
|
||||
const match = document.cookie.match(/(?:^|;\s*)authToken=([^;]*)/);
|
||||
return match ? decodeURIComponent(match[1]) : null;
|
||||
};
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
// lib/gallery-views.tsx
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { ExamAnswer } from "@/types/exam";
|
||||
import { GalleryViews } from "@/types/gallery";
|
||||
|
||||
// Define the ExamResults type if not already defined
|
||||
interface ExamResults {
|
||||
score: number;
|
||||
totalQuestions: number;
|
||||
answers: string[];
|
||||
}
|
||||
|
||||
interface LinkedViews {
|
||||
id: string;
|
||||
content: React.ReactNode;
|
||||
answers: ExamAnswer[]; // or more specific type based on your answer structure
|
||||
}
|
||||
|
||||
export const getResultViews = (examResults: ExamResults | null) => [
|
||||
@ -104,9 +102,9 @@ export const getResultViews = (examResults: ExamResults | null) => [
|
||||
},
|
||||
];
|
||||
|
||||
export const getLinkedViews = (): LinkedViews[] => [
|
||||
export const getLinkedViews = (): GalleryViews[] => [
|
||||
{
|
||||
id: "1",
|
||||
id: 1,
|
||||
content: (
|
||||
<Link
|
||||
href="https://www.facebook.com/share/g/15jdqESvWV/?mibextid=wwXIfr"
|
||||
|
||||
Reference in New Issue
Block a user