diff --git a/.env.example b/.env.example index 898f524..343f7c2 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ # ============================================================================== PG_PASS= AUTHENTIK_SECRET_KEY= +ENCRYPTION_KEY= # ============================================================================== # HOST CONFIGURATION diff --git a/components/Landing.tsx b/components/Landing.tsx index 22a91c1..b9b61b1 100644 --- a/components/Landing.tsx +++ b/components/Landing.tsx @@ -39,11 +39,13 @@ export const Landing: React.FC = ({ onGenerate, onCreateManual, on const setMode = (newMode: 'HOST' | 'JOIN') => { setModeState(newMode); - const newParams = new URLSearchParams(searchParams); + const newParams = new URLSearchParams(); + const modalParam = searchParams.get('modal'); + if (modalParam) { + newParams.set('modal', modalParam); + } if (newMode === 'HOST') { newParams.set('mode', 'host'); - } else { - newParams.delete('mode'); } setSearchParams(newParams, { replace: true }); }; @@ -58,44 +60,33 @@ export const Landing: React.FC = ({ onGenerate, onCreateManual, on const defaultConfigOpen = modalParam === 'settings'; const accountSettingsOpen = modalParam === 'account'; - const setLibraryOpen = (open: boolean) => { - const newParams = new URLSearchParams(searchParams); - if (open) { - newParams.set('modal', 'library'); - } else { - newParams.delete('modal'); + const buildCleanParams = (updates: Record) => { + const newParams = new URLSearchParams(); + const modeParam = searchParams.get('mode'); + if (modeParam) newParams.set('mode', modeParam); + + for (const [key, value] of Object.entries(updates)) { + if (value !== null) { + newParams.set(key, value); + } } - setSearchParams(newParams); + return newParams; + }; + + const setLibraryOpen = (open: boolean) => { + setSearchParams(buildCleanParams({ modal: open ? 'library' : null })); }; const setPreferencesOpen = (open: boolean) => { - const newParams = new URLSearchParams(searchParams); - if (open) { - newParams.set('modal', 'preferences'); - } else { - newParams.delete('modal'); - } - setSearchParams(newParams); + setSearchParams(buildCleanParams({ modal: open ? 'preferences' : null })); }; const setDefaultConfigOpen = (open: boolean) => { - const newParams = new URLSearchParams(searchParams); - if (open) { - newParams.set('modal', 'settings'); - } else { - newParams.delete('modal'); - } - setSearchParams(newParams); + setSearchParams(buildCleanParams({ modal: open ? 'settings' : null })); }; const setAccountSettingsOpen = (open: boolean) => { - const newParams = new URLSearchParams(searchParams); - if (open) { - newParams.set('modal', 'account'); - } else { - newParams.delete('modal'); - } - setSearchParams(newParams); + setSearchParams(buildCleanParams({ modal: open ? 'account' : null })); }; const [selectedFiles, setSelectedFiles] = useState([]); diff --git a/components/QuizEditor.tsx b/components/QuizEditor.tsx index 2529fcf..d1cd804 100644 --- a/components/QuizEditor.tsx +++ b/components/QuizEditor.tsx @@ -39,11 +39,20 @@ export const QuizEditor: React.FC = ({ const [config, setConfig] = useState( initialQuiz.config || defaultConfig || DEFAULT_GAME_CONFIG ); + const [hasAppliedDefaultConfig, setHasAppliedDefaultConfig] = useState(!!initialQuiz.config); + + useEffect(() => { + if (!hasAppliedDefaultConfig && defaultConfig && defaultConfig !== DEFAULT_GAME_CONFIG) { + setConfig(defaultConfig); + setHasAppliedDefaultConfig(true); + } + }, [defaultConfig, hasAppliedDefaultConfig]); useBodyScrollLock(!!showDeleteConfirm); const handleConfigChange = useCallback((newConfig: GameConfig) => { setConfig(newConfig); + setHasAppliedDefaultConfig(true); onConfigChange?.(newConfig); }, [onConfigChange]); @@ -191,7 +200,7 @@ export const QuizEditor: React.FC = ({ {showSaveButton && (