Add sharing
This commit is contained in:
parent
240ce28692
commit
8a11275849
16 changed files with 1996 additions and 10 deletions
|
|
@ -8,6 +8,7 @@ interface UseQuizLibraryReturn {
|
|||
loading: boolean;
|
||||
loadingQuizId: string | null;
|
||||
deletingQuizId: string | null;
|
||||
sharingQuizId: string | null;
|
||||
saving: boolean;
|
||||
exporting: boolean;
|
||||
importing: boolean;
|
||||
|
|
@ -18,6 +19,8 @@ interface UseQuizLibraryReturn {
|
|||
updateQuiz: (id: string, quiz: Quiz) => Promise<void>;
|
||||
updateQuizConfig: (id: string, config: GameConfig) => Promise<void>;
|
||||
deleteQuiz: (id: string) => Promise<void>;
|
||||
shareQuiz: (id: string) => Promise<string>;
|
||||
unshareQuiz: (id: string) => Promise<void>;
|
||||
exportQuizzes: (quizIds: string[]) => Promise<void>;
|
||||
importQuizzes: (quizzes: ExportedQuiz[]) => Promise<void>;
|
||||
parseImportFile: (file: File) => Promise<QuizExportFile>;
|
||||
|
|
@ -31,6 +34,7 @@ export const useQuizLibrary = (): UseQuizLibraryReturn => {
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [loadingQuizId, setLoadingQuizId] = useState<string | null>(null);
|
||||
const [deletingQuizId, setDeletingQuizId] = useState<string | null>(null);
|
||||
const [sharingQuizId, setSharingQuizId] = useState<string | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [exporting, setExporting] = useState(false);
|
||||
const [importing, setImporting] = useState(false);
|
||||
|
|
@ -267,6 +271,70 @@ export const useQuizLibrary = (): UseQuizLibraryReturn => {
|
|||
setDeletingQuizId(null);
|
||||
}
|
||||
}, [authFetch]);
|
||||
|
||||
const shareQuiz = useCallback(async (id: string): Promise<string> => {
|
||||
setSharingQuizId(id);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await authFetch(`/api/quizzes/${id}/share`, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = response.status === 404
|
||||
? 'Quiz not found.'
|
||||
: 'Failed to share quiz.';
|
||||
throw new Error(errorText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setQuizzes(prev => prev.map(q =>
|
||||
q.id === id ? { ...q, shareToken: data.shareToken, isShared: true } : q
|
||||
));
|
||||
toast.success('Quiz shared! Link copied to clipboard.');
|
||||
return data.shareToken;
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Failed to share quiz';
|
||||
if (!message.includes('redirecting')) {
|
||||
toast.error(message);
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
setSharingQuizId(null);
|
||||
}
|
||||
}, [authFetch]);
|
||||
|
||||
const unshareQuiz = useCallback(async (id: string): Promise<void> => {
|
||||
setSharingQuizId(id);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await authFetch(`/api/quizzes/${id}/share`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = response.status === 404
|
||||
? 'Quiz not found.'
|
||||
: 'Failed to stop sharing quiz.';
|
||||
throw new Error(errorText);
|
||||
}
|
||||
|
||||
setQuizzes(prev => prev.map(q =>
|
||||
q.id === id ? { ...q, shareToken: undefined, isShared: false } : q
|
||||
));
|
||||
toast.success('Quiz is no longer shared');
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Failed to stop sharing quiz';
|
||||
if (!message.includes('redirecting')) {
|
||||
toast.error(message);
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
setSharingQuizId(null);
|
||||
}
|
||||
}, [authFetch]);
|
||||
|
||||
const exportQuizzes = useCallback(async (quizIds: string[]): Promise<void> => {
|
||||
if (quizIds.length === 0) {
|
||||
|
|
@ -379,6 +447,7 @@ export const useQuizLibrary = (): UseQuizLibraryReturn => {
|
|||
loading,
|
||||
loadingQuizId,
|
||||
deletingQuizId,
|
||||
sharingQuizId,
|
||||
saving,
|
||||
exporting,
|
||||
importing,
|
||||
|
|
@ -389,6 +458,8 @@ export const useQuizLibrary = (): UseQuizLibraryReturn => {
|
|||
updateQuiz,
|
||||
updateQuizConfig,
|
||||
deleteQuiz,
|
||||
shareQuiz,
|
||||
unshareQuiz,
|
||||
exportQuizzes,
|
||||
importQuizzes,
|
||||
parseImportFile,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue