Add admin help center entry points
This commit is contained in:
114
resources/js/admin/mobile/HelpArticlePage.tsx
Normal file
114
resources/js/admin/mobile/HelpArticlePage.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { YStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { YGroup } from '@tamagui/group';
|
||||
import { ListItem } from '@tamagui/list-item';
|
||||
|
||||
import { MobileShell } from './components/MobileShell';
|
||||
import { MobileCard, CTAButton, SkeletonCard } from './components/Primitives';
|
||||
import { useAdminTheme } from './theme';
|
||||
import { useBackNavigation } from './hooks/useBackNavigation';
|
||||
import { adminPath, ADMIN_FAQ_PATH } from '../constants';
|
||||
import { fetchHelpCenterArticle, type HelpCenterArticle } from '../api';
|
||||
|
||||
export default function MobileHelpArticlePage() {
|
||||
const { slug } = useParams<{ slug: string }>();
|
||||
const { t, i18n } = useTranslation(['management', 'dashboard']);
|
||||
const theme = useAdminTheme();
|
||||
const back = useBackNavigation(ADMIN_FAQ_PATH);
|
||||
const navigate = useNavigate();
|
||||
const locale = i18n.language;
|
||||
|
||||
const { data, isLoading, isError, refetch } = useQuery({
|
||||
queryKey: ['mobile', 'help-article', slug, locale],
|
||||
enabled: Boolean(slug),
|
||||
queryFn: () => fetchHelpCenterArticle(slug ?? '', locale),
|
||||
});
|
||||
|
||||
const article: HelpCenterArticle | null = data ?? null;
|
||||
|
||||
return (
|
||||
<MobileShell activeTab="profile" title={article?.title ?? t('common.help', 'Help')} onBack={back}>
|
||||
{isLoading ? (
|
||||
<YStack space="$2">
|
||||
<SkeletonCard height={120} />
|
||||
<SkeletonCard height={160} />
|
||||
</YStack>
|
||||
) : null}
|
||||
|
||||
{isError ? (
|
||||
<MobileCard>
|
||||
<YStack space="$2">
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
|
||||
{t('dashboard:help.error', 'Help could not be loaded.')}
|
||||
</Text>
|
||||
<CTAButton
|
||||
label={t('common.retry', 'Erneut versuchen')}
|
||||
onPress={() => refetch()}
|
||||
fullWidth={false}
|
||||
/>
|
||||
</YStack>
|
||||
</MobileCard>
|
||||
) : null}
|
||||
|
||||
{!isLoading && article ? (
|
||||
<YStack space="$3">
|
||||
<MobileCard>
|
||||
<YStack space="$2">
|
||||
<Text fontSize="$lg" fontWeight="800" color={theme.textStrong}>
|
||||
{article.title}
|
||||
</Text>
|
||||
{article.updated_at ? (
|
||||
<Text fontSize="$xs" color={theme.muted}>
|
||||
{t('help.article.updated', 'Aktualisiert')}:{' '}
|
||||
{new Date(article.updated_at).toLocaleDateString(locale, {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</Text>
|
||||
) : null}
|
||||
<div
|
||||
className="prose prose-sm max-w-none dark:prose-invert [&_table]:w-full [&_table]:text-sm [&_:where(p,ul,ol,li)]:text-foreground [&_:where(h1,h2,h3,h4,h5,h6)]:text-foreground"
|
||||
dangerouslySetInnerHTML={{ __html: article.body_html ?? article.body_markdown ?? '' }}
|
||||
/>
|
||||
</YStack>
|
||||
</MobileCard>
|
||||
|
||||
{article.related && article.related.length > 0 ? (
|
||||
<MobileCard>
|
||||
<YStack space="$2">
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
|
||||
{t('help.article.relatedTitle', 'Weitere Artikel')}
|
||||
</Text>
|
||||
<YGroup {...({ borderRadius: '$4', borderWidth: 1, borderColor: theme.border, overflow: 'hidden' } as any)}>
|
||||
{article.related.map((rel) => (
|
||||
<YGroup.Item key={rel.slug}>
|
||||
<ListItem
|
||||
hoverTheme
|
||||
pressTheme
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$3"
|
||||
onPress={() => navigate(adminPath(`/mobile/help/${encodeURIComponent(rel.slug)}`))}
|
||||
title={
|
||||
<Text fontSize="$sm" color={theme.textStrong}>
|
||||
{rel.title ?? rel.slug}
|
||||
</Text>
|
||||
}
|
||||
iconAfter={<ChevronRight size={16} color={theme.muted} />}
|
||||
/>
|
||||
</YGroup.Item>
|
||||
))}
|
||||
</YGroup>
|
||||
</YStack>
|
||||
</MobileCard>
|
||||
) : null}
|
||||
</YStack>
|
||||
) : null}
|
||||
</MobileShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user