Update README.md to provide a comprehensive overview of the ScriptShare platform, including features, tech stack, setup instructions, admin capabilities, and contribution guidelines.

This commit is contained in:
2025-08-12 22:31:26 +01:00
parent 978b9b26bc
commit aa10ea0b26
64 changed files with 12998 additions and 2 deletions

View File

@ -0,0 +1,212 @@
import { createContext, useContext, useEffect, useState } from 'react';
import { generateId } from '@/lib/utils';
import { AdminUser, createSuperUser, createAdminUser, hasPermission } from '@/lib/admin';
interface User extends AdminUser {}
interface AuthContextType {
user: User | null;
isLoading: boolean;
login: (email: string, password: string) => Promise<boolean>;
register: (email: string, username: string, displayName: string, password: string) => Promise<boolean>;
logout: () => void;
updateProfile: (updates: Partial<User>) => Promise<boolean>;
createSuperUser: (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }) => Promise<boolean>;
createAdminUser: (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }) => Promise<boolean>;
hasPermission: (permission: string) => boolean;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
interface AuthProviderProps {
children: React.ReactNode;
}
export function AuthProvider({ children }: AuthProviderProps) {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Check for existing session on mount
const checkAuth = async () => {
try {
const token = localStorage.getItem('scriptshare-auth-token');
if (token) {
// In a real app, you'd validate the token with your backend
// For now, we'll just check if it exists
const userData = localStorage.getItem('scriptshare-user-data');
if (userData) {
setUser(JSON.parse(userData));
}
}
} catch (error) {
console.error('Auth check failed:', error);
} finally {
setIsLoading(false);
}
};
checkAuth();
}, []);
const login = async (email: string, _password: string): Promise<boolean> => {
try {
setIsLoading(true);
// In a real app, you'd make an API call to your backend
// For now, we'll simulate a successful login
await new Promise(resolve => setTimeout(resolve, 1000));
// Simulate user data
const mockUser: User = {
id: generateId(),
email,
username: email.split('@')[0],
displayName: email.split('@')[0],
isAdmin: false,
isModerator: false,
isSuperUser: false,
permissions: [],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
const token = generateId();
localStorage.setItem('scriptshare-auth-token', token);
localStorage.setItem('scriptshare-user-data', JSON.stringify(mockUser));
setUser(mockUser);
return true;
} catch (error) {
console.error('Login failed:', error);
return false;
} finally {
setIsLoading(false);
}
};
const register = async (email: string, username: string, displayName: string, _password: string): Promise<boolean> => {
try {
setIsLoading(true);
// In a real app, you'd make an API call to your backend
// For now, we'll simulate a successful registration
await new Promise(resolve => setTimeout(resolve, 1000));
const mockUser: User = {
id: generateId(),
email,
username,
displayName,
isAdmin: false,
isModerator: false,
isSuperUser: false,
permissions: [],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
const token = generateId();
localStorage.setItem('scriptshare-auth-token', token);
localStorage.setItem('scriptshare-user-data', JSON.stringify(mockUser));
setUser(mockUser);
return true;
} catch (error) {
console.error('Registration failed:', error);
return false;
} finally {
setIsLoading(false);
}
};
const logout = () => {
localStorage.removeItem('scriptshare-auth-token');
localStorage.removeItem('scriptshare-user-data');
setUser(null);
};
const updateProfile = async (updates: Partial<User>): Promise<boolean> => {
try {
if (!user) return false;
const updatedUser = { ...user, ...updates, updatedAt: new Date().toISOString() };
localStorage.setItem('scriptshare-user-data', JSON.stringify(updatedUser));
setUser(updatedUser);
return true;
} catch (error) {
console.error('Profile update failed:', error);
return false;
}
};
const createSuperUserLocal = async (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }): Promise<boolean> => {
try {
// In a real app, you'd make an API call to your backend
// For now, we'll simulate creating a superuser
await new Promise(resolve => setTimeout(resolve, 1000));
const newSuperUser = createSuperUser(userData);
// Store in localStorage for demo purposes
const existingUsers = JSON.parse(localStorage.getItem('scriptshare-admin-users') || '[]');
existingUsers.push(newSuperUser);
localStorage.setItem('scriptshare-admin-users', JSON.stringify(existingUsers));
return true;
} catch (error) {
console.error('Super user creation failed:', error);
return false;
}
};
const createAdminUserLocal = async (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }): Promise<boolean> => {
try {
// In a real app, you'd make an API call to your backend
// For now, we'll simulate creating an admin user
await new Promise(resolve => setTimeout(resolve, 1000));
const newAdminUser = createAdminUser(userData);
// Store in localStorage for demo purposes
const existingUsers = JSON.parse(localStorage.getItem('scriptshare-admin-users') || '[]');
existingUsers.push(newAdminUser);
localStorage.setItem('scriptshare-admin-users', JSON.stringify(existingUsers));
return true;
} catch (error) {
console.error('Admin user creation failed:', error);
return false;
}
};
const hasPermission = (permission: string): boolean => {
return hasPermission(user, permission);
};
const value = {
user,
isLoading,
login,
register,
logout,
updateProfile,
createSuperUser: createSuperUserLocal,
createAdminUser: createAdminUserLocal,
hasPermission,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}