72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import type { Result } from '@/lib/contracts/Result';
|
|
import type { ProfileViewData } from '@/lib/view-data/ProfileViewData';
|
|
import { ProfileSettingsTemplate } from '@/templates/ProfileSettingsTemplate';
|
|
import { Box } from '@/ui/Box';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Text } from '@/ui/Text';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { ProgressLine } from '@/components/shared/ProgressLine';
|
|
import { ShieldAlert } from 'lucide-react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useState } from 'react';
|
|
import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts';
|
|
|
|
interface ProfileSettingsPageClientProps extends ClientWrapperProps<ProfileViewData> {
|
|
onSave: (updates: { bio?: string; country?: string }) => Promise<Result<void, string>>;
|
|
}
|
|
|
|
export function ProfileSettingsPageClient({ viewData, onSave }: ProfileSettingsPageClientProps) {
|
|
const router = useRouter();
|
|
const [isSaving, setIsSaving] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const [bio, setBio] = useState(viewData.driver.bio || '');
|
|
const [country, setCountry] = useState(viewData.driver.countryCode);
|
|
|
|
const handleSave = async () => {
|
|
setIsSaving(true);
|
|
setError(null);
|
|
try {
|
|
const result = await onSave({ bio, country });
|
|
if (result.isErr()) {
|
|
setError(result.getError());
|
|
} else {
|
|
router.refresh();
|
|
}
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Failed to save settings');
|
|
} finally {
|
|
setIsSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<ProgressLine isLoading={isSaving} />
|
|
{error && (
|
|
<Box position="fixed" top={4} right={4} zIndex={50} maxWidth="md">
|
|
<Box bg="var(--ui-color-bg-surface)" p={4} rounded="md" border borderColor="var(--ui-color-intent-critical)">
|
|
<Stack direction="row" align="center" gap={3}>
|
|
<Icon icon={ShieldAlert} size={5} color="var(--ui-color-intent-critical)" />
|
|
<Box>
|
|
<Text weight="bold" variant="critical">Update Failed</Text>
|
|
<Text size="sm" variant="low">{error}</Text>
|
|
</Box>
|
|
</Stack>
|
|
</Box>
|
|
</Box>
|
|
)}
|
|
<ProfileSettingsTemplate
|
|
viewData={viewData}
|
|
bio={bio}
|
|
country={country}
|
|
onBioChange={setBio}
|
|
onCountryChange={setCountry}
|
|
onSave={handleSave}
|
|
/>
|
|
</>
|
|
);
|
|
}
|