mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
dev day #69
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
Tab,
|
||||
TabList,
|
||||
TabPanel,
|
||||
TabPanels,
|
||||
Tabs,
|
||||
Heading,
|
||||
Text,
|
||||
useToast,
|
||||
VStack,
|
||||
HStack,
|
||||
Link as ChakraLink,
|
||||
} from '@chakra-ui/react';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import api from '../services/api';
|
||||
|
||||
const SemiAdminPage: React.FC = () => {
|
||||
const { user, updateUser } = useAuth();
|
||||
const splitName = (full?: string) => {
|
||||
const v = String(full || '').trim();
|
||||
if (!v) return { fn: '', ln: '' };
|
||||
const parts = v.split(/\s+/);
|
||||
if (parts.length === 1) return { fn: parts[0], ln: '' };
|
||||
return { fn: parts[0], ln: parts.slice(1).join(' ') };
|
||||
};
|
||||
const init = splitName(user?.name);
|
||||
const [firstName, setFirstName] = useState(init.fn);
|
||||
const [lastName, setLastName] = useState(init.ln);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [prefsToken, setPrefsToken] = useState<string>('');
|
||||
const toast = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
const s = splitName(user?.name);
|
||||
setFirstName(s.fn);
|
||||
setLastName(s.ln);
|
||||
}, [user?.name]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const res = await api.get('/newsletter/token/me');
|
||||
setPrefsToken(res.data?.token || '');
|
||||
} catch {}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const handleSave = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setIsSaving(true);
|
||||
try {
|
||||
const res = await api.put('/me', { first_name: firstName, last_name: lastName });
|
||||
const updated = res.data?.user;
|
||||
if (updated) {
|
||||
const n = `${updated.first_name || firstName} ${updated.last_name || lastName}`.trim();
|
||||
updateUser({ name: n });
|
||||
}
|
||||
toast({ title: 'Uloženo', description: 'Osobní údaje byly aktualizovány.', status: 'success', duration: 3000 });
|
||||
} catch (err: any) {
|
||||
toast({ title: 'Chyba', description: err?.response?.data?.error || 'Nelze uložit změny', status: 'error' });
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const prefsUrl = prefsToken ? `/newsletter/preferences?token=${encodeURIComponent(prefsToken)}` : '';
|
||||
|
||||
return (
|
||||
<Container maxW="5xl" py={8}>
|
||||
<Heading size="lg" mb={6}>Fan zóna</Heading>
|
||||
<Tabs colorScheme="blue" isFitted variant="enclosed">
|
||||
<TabList>
|
||||
<Tab>Osobní údaje</Tab>
|
||||
<Tab>Newsletter</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<Box as="form" onSubmit={handleSave} maxW="lg">
|
||||
<VStack align="stretch" spacing={4}>
|
||||
<FormControl>
|
||||
<FormLabel>Jméno</FormLabel>
|
||||
<Input value={firstName} onChange={(e) => setFirstName(e.target.value)} placeholder="Jméno" />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>Příjmení</FormLabel>
|
||||
<Input value={lastName} onChange={(e) => setLastName(e.target.value)} placeholder="Příjmení" />
|
||||
</FormControl>
|
||||
<HStack>
|
||||
<Button type="submit" colorScheme="blue" isLoading={isSaving}>Uložit</Button>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<VStack align="start" spacing={4}>
|
||||
<Text>Spravujte předvolby newsletteru nebo se odhlaste.</Text>
|
||||
{prefsUrl ? (
|
||||
<Button as={ChakraLink} href={prefsUrl} colorScheme="blue">Otevřít nastavení newsletteru</Button>
|
||||
) : (
|
||||
<Text>Načítám odkaz na nastavení…</Text>
|
||||
)}
|
||||
</VStack>
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default SemiAdminPage;
|
||||
Reference in New Issue
Block a user