chore: initial import to Nexus_Edu
This commit is contained in:
89
src/lib/auth-context.tsx
Normal file
89
src/lib/auth-context.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
"use client";
|
||||
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
import { UserProfileDto } from '../../UI_DTO';
|
||||
import { authService, subscribeApiMode } from '@/services/api';
|
||||
import { useRouter, usePathname } from 'next/navigation';
|
||||
|
||||
interface AuthContextType {
|
||||
user: UserProfileDto | null;
|
||||
loading: boolean;
|
||||
login: (username: string, password: string) => Promise<void>;
|
||||
logout: () => void;
|
||||
register: (data: any) => Promise<void>;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
|
||||
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const [user, setUser] = useState<UserProfileDto | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname() || '';
|
||||
|
||||
const checkAuth = async () => {
|
||||
try {
|
||||
const userData = await authService.me();
|
||||
setUser(userData);
|
||||
} catch (e) {
|
||||
setUser(null);
|
||||
if (!pathname.includes('/login')) {
|
||||
router.push('/login');
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Re-check auth when API mode changes (Strategy Pattern hook)
|
||||
useEffect(() => {
|
||||
return subscribeApiMode(() => {
|
||||
setLoading(true);
|
||||
checkAuth();
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
checkAuth();
|
||||
}, []);
|
||||
|
||||
const login = async (username: string, password: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await authService.login(username, password);
|
||||
setUser(res.user);
|
||||
router.push('/dashboard');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const register = async (data: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await authService.register(data);
|
||||
setUser(res.user);
|
||||
router.push('/dashboard');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
setUser(null);
|
||||
localStorage.removeItem('token');
|
||||
router.push('/login');
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ user, loading, login, logout, register }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAuth = () => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) throw new Error('useAuth must be used within an AuthProvider');
|
||||
return context;
|
||||
};
|
||||
35
src/lib/db.ts
Normal file
35
src/lib/db.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
// This file would typically use mysql2/promise
|
||||
// import mysql from 'mysql2/promise';
|
||||
|
||||
// Mock DB Configuration storage (In-memory for demo, use env vars in prod)
|
||||
let dbConfig = {
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
user: 'root',
|
||||
password: '',
|
||||
database: 'edunexus'
|
||||
};
|
||||
|
||||
// Mock Connection Pool
|
||||
export const db = {
|
||||
query: async (sql: string, params?: any[]) => {
|
||||
// In a real app:
|
||||
// const connection = await mysql.createConnection(dbConfig);
|
||||
// const [rows] = await connection.execute(sql, params);
|
||||
// return rows;
|
||||
|
||||
console.log(`[MockDB] Executing SQL: ${sql}`, params);
|
||||
return [];
|
||||
},
|
||||
testConnection: async (config: typeof dbConfig) => {
|
||||
// Simulate connection attempt
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
if (config.host === 'error') throw new Error('Connection timed out');
|
||||
|
||||
// Update active config
|
||||
dbConfig = config;
|
||||
return true;
|
||||
},
|
||||
getConfig: () => dbConfig
|
||||
};
|
||||
24
src/lib/server-utils.ts
Normal file
24
src/lib/server-utils.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
// Simulate database latency
|
||||
export const dbDelay = () => new Promise(resolve => setTimeout(resolve, 500));
|
||||
|
||||
// Standardize JSON success response
|
||||
export function successResponse(data: any, status = 200) {
|
||||
return NextResponse.json(data, { status });
|
||||
}
|
||||
|
||||
// Standardize JSON error response
|
||||
export function errorResponse(message: string, status = 400) {
|
||||
return NextResponse.json({ success: false, message }, { status });
|
||||
}
|
||||
|
||||
// Helper to extract token from header
|
||||
export function extractToken(request: Request): string | null {
|
||||
const authHeader = request.headers.get('authorization');
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
return null;
|
||||
}
|
||||
return authHeader.split(' ')[1];
|
||||
}
|
||||
Reference in New Issue
Block a user