Add settings endpoints and registration status check: implement new API endpoints for settings management, including registration status retrieval, and update the registration command handler to enforce registration rules based on site settings.

This commit is contained in:
Leonid Pershin
2026-07-25 07:48:17 +03:00
parent 1bdc3323ab
commit c53848477f
33 changed files with 1289 additions and 17 deletions
@@ -0,0 +1,62 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { HttpError } from '@/shared/api/client'
import { Button } from '@/shared/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/shared/ui/card'
import { toast } from '@/shared/ui/toast-store'
import { getSiteSettings, updateSiteSettings } from './api'
export function SettingsPanel() {
const { t } = useTranslation()
const queryClient = useQueryClient()
const [registrationEnabled, setRegistrationEnabled] = useState(false)
const { data, isLoading } = useQuery({
queryKey: ['admin', 'settings'],
queryFn: getSiteSettings,
})
useEffect(() => {
if (data) setRegistrationEnabled(data.registrationEnabled)
}, [data])
const save = useMutation({
mutationFn: () => updateSiteSettings({ registrationEnabled }),
onSuccess: () => {
toast.success(t('settings.saved'))
void queryClient.invalidateQueries({ queryKey: ['admin', 'settings'] })
},
onError: (error: unknown) =>
toast.error(error instanceof HttpError ? error.detail : t('common.error')),
})
return (
<div className="flex flex-col gap-4">
<h2 className="crt-glow text-xl font-semibold">{t('admin.settings.title')}</h2>
<Card>
<CardHeader>
<CardTitle>{t('admin.settings.registration')}</CardTitle>
<CardDescription>{t('admin.settings.registrationHint')}</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<label className="flex items-center gap-2 text-sm">
<input
type="checkbox"
checked={registrationEnabled}
disabled={isLoading}
onChange={(e) => setRegistrationEnabled(e.target.checked)}
/>
{t('admin.settings.registrationLabel')}
</label>
<div>
<Button size="sm" disabled={isLoading || save.isPending} onClick={() => save.mutate()}>
{t('common.save')}
</Button>
</div>
</CardContent>
</Card>
</div>
)
}
@@ -0,0 +1,10 @@
import { apiRequest } from '@/shared/api/client'
import type { SiteSettings } from '@/shared/api/types'
export function getSiteSettings() {
return apiRequest<SiteSettings>('/admin/settings')
}
export function updateSiteSettings(body: SiteSettings) {
return apiRequest<void>('/admin/settings', { method: 'PUT', body })
}