admin
All checks were successful
Build and Publish Images / build-and-push (push) Successful in 17s

This commit is contained in:
arrelin
2026-03-06 17:46:38 +03:00
parent ad2f6a5883
commit c9dafa4cc6
2 changed files with 16 additions and 9 deletions

View File

@@ -34,17 +34,24 @@ services:
frontend: frontend:
image: 192.168.31.100:3847/arrelin/wedding-frontend:latest image: 192.168.31.100:3847/arrelin/wedding-frontend:latest
container_name: wedding_frontend container_name: wedding_frontend
expose:
- "80"
depends_on: depends_on:
- backend - backend
networks: networks:
- app_network - app_network
- coolify
restart: unless-stopped restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.routers.wedding-frontend.rule=Host(`weddinge.duckdns.org`)
- traefik.http.routers.wedding-frontend.entrypoints=https
- traefik.http.routers.wedding-frontend.tls=true
- traefik.http.services.wedding-frontend.loadbalancer.server.port=80
networks: networks:
app_network: app_network:
driver: bridge driver: bridge
coolify:
external: true
volumes: volumes:
postgres_data: postgres_data:

View File

@@ -16,24 +16,24 @@ interface Response {
export default function Admin() { export default function Admin() {
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const [authed, setAuthed] = useState(false) const [authed, setAuthed] = useState(false)
const [error, setError] = useState(false) const [error, setError] = useState<string | null>(null)
const [responses, setResponses] = useState<Response[]>([]) const [responses, setResponses] = useState<Response[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const handleLogin = async (e: React.FormEvent) => { const handleLogin = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
setLoading(true) setLoading(true)
setError(false) setError(null)
try { try {
const res = await fetch('/api/admin/responses', { const res = await fetch('/api/admin/responses', {
headers: { 'x-admin-password': password }, headers: { 'x-admin-password': password },
}) })
if (res.status === 401) { setError(true); return } if (res.status === 401) { setError('Неверный пароль'); return }
if (!res.ok) throw new Error() if (!res.ok) throw new Error(`Ошибка сервера: ${res.status}`)
setResponses(await res.json()) setResponses(await res.json())
setAuthed(true) setAuthed(true)
} catch { } catch (err) {
setError(true) setError(err instanceof Error ? err.message : 'Не удалось подключиться к серверу')
} finally { } finally {
setLoading(false) setLoading(false)
} }
@@ -52,7 +52,7 @@ export default function Admin() {
onChange={e => setPassword(e.target.value)} onChange={e => setPassword(e.target.value)}
autoFocus autoFocus
/> />
{error && <p className="admin-gate-error">Неверный пароль</p>} {error && <p className="admin-gate-error">{error}</p>}
<button className="admin-gate-btn" type="submit" disabled={loading}> <button className="admin-gate-btn" type="submit" disabled={loading}>
{loading ? 'Загрузка...' : 'Войти'} {loading ? 'Загрузка...' : 'Войти'}
</button> </button>