diff --git a/be/apps/dashboard/src/modules/auth/components/registration-wizard/RegistrationWizard.tsx b/be/apps/dashboard/src/modules/auth/components/registration-wizard/RegistrationWizard.tsx index d9970652..e83fe3b8 100644 --- a/be/apps/dashboard/src/modules/auth/components/registration-wizard/RegistrationWizard.tsx +++ b/be/apps/dashboard/src/modules/auth/components/registration-wizard/RegistrationWizard.tsx @@ -43,6 +43,7 @@ export const RegistrationWizard: FC = () => { const slugManuallyEditedRef = useRef(false) const [lockedTenantSlug, setLockedTenantSlug] = useState(null) const siteDefaultsAppliedRef = useRef(false) + const siteAutofillAppliedRef = useRef(false) const siteSchemaQuery = useQuery({ queryKey: ['welcome', 'site-schema'], @@ -151,6 +152,72 @@ export const RegistrationWizard: FC = () => { [siteFieldMap], ) + useEffect(() => { + if (siteAutofillAppliedRef.current) { + return + } + if (!authUser) { + return + } + if (!siteFieldMap || siteFieldMap.size === 0) { + return + } + + const resolveDisplayName = () => { + const rawName = authUser.name?.trim() + if (rawName) { + return rawName + } + const emailLocal = authUser.email?.split('@')[0]?.trim() + if (emailLocal) { + return emailLocal + } + return 'My' + } + + const formatPossessive = (value: string) => { + if (!value) { + return 'My' + } + const trimmed = value.trim() + return /s$/i.test(trimmed) ? `${trimmed}'` : `${trimmed}'s` + } + + const isEmptyValue = (value: unknown) => { + if (value == null) { + return true + } + if (typeof value === 'string') { + return value.trim().length === 0 + } + return false + } + + const prefillField = (key: TenantSiteFieldKey, value: string) => { + if (!siteFieldMap.has(key)) { + return false + } + const current = form.getFieldValue(key) + if (!isEmptyValue(current)) { + return false + } + form.setFieldValue(key, () => value) + return true + } + + const displayName = resolveDisplayName() + const possessiveName = formatPossessive(displayName) + const defaultSiteName = `${possessiveName} Afilmory` + const defaultTitle = defaultSiteName + const defaultDescription = `A curated photo gallery by ${displayName} on Afilmory.` + + prefillField('site.name', defaultSiteName) + prefillField('site.title', defaultTitle) + prefillField('site.description', defaultDescription) + + siteAutofillAppliedRef.current = true + }, [authUser, form, siteFieldMap]) + const getStepFields = useCallback( (stepId: (typeof REGISTRATION_STEPS)[number]['id']) => { if (stepId === 'site') { @@ -431,6 +498,7 @@ export const RegistrationWizard: FC = () => { form, formValues, isLoading, + lockedTenantSlug, onFieldInteraction, siteFieldErrors, siteSchema, diff --git a/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx b/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx index 685c6343..b8931cc5 100644 --- a/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx +++ b/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx @@ -276,12 +276,6 @@ export function DashboardOverview() { }, ] - const syncSummary = [ - { key: 'synced', value: stats.sync.synced }, - { key: 'pending', value: stats.sync.pending }, - { key: 'conflict', value: stats.sync.conflicts }, - ] as const - return (
@@ -309,77 +303,28 @@ export function DashboardOverview() { ))}
-
- -
-

最近活动

-

- {data?.recentActivity?.length - ? `展示最近 ${data.recentActivity.length} 次上传和同步记录` - : '还没有任何上传,快来添加第一张照片吧~'} -

+ +
+

最近活动

+

+ {data?.recentActivity?.length + ? `展示最近 ${data.recentActivity.length} 次上传和同步记录` + : '还没有任何上传,快来添加第一张照片吧~'} +

+
+ + {isLoading ? ( +
+ {Array.from({ length: 3 }, (_, i) => `activity-skeleton-${i}`).map((key) => ( + + ))}
- - {isLoading ? ( -
- {Array.from({ length: 3 }, (_, i) => `activity-skeleton-${i}`).map((key) => ( - - ))} -
- ) : isError ? ( -
无法获取活动数据,请稍后再试。
- ) : ( - - )} -
- - -
-

同步概览

-

- 了解当前同步状态,及时处理异常项。 -

-
- -
- {syncSummary.map((entry) => { - const meta = STATUS_META[entry.key] - const percent = statusTotal ? Math.round((entry.value / statusTotal) * 100) : 0 - - return ( -
-
- - - {meta.label} - - - {plainNumberFormatter.format(entry.value)} - {percent}% - -
-
-
0 ? 4 : 0) : 0}%` }} - /> -
-
- ) - })} -
- - - -
- {statusTotal === 0 - ? '暂无同步任务,添加照片后即可查看同步健康度。' - : syncCompletion !== null && syncCompletion >= 0.85 - ? '同步状态良好,保持当前处理效率即可。' - : '存在待处理或冲突的项目,建议尽快检查同步日志。'} -
- -
+ ) : isError ? ( +
无法获取活动数据,请稍后再试。
+ ) : ( + + )} +
) diff --git a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx index 674aa316..2acc25df 100644 --- a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx +++ b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx @@ -4,6 +4,7 @@ import { useAtomValue } from 'jotai' import { DynamicIcon } from 'lucide-react/dynamic' import { viewportAtom } from '~/atoms/viewport' +import { LinearBorderPanel } from '~/components/common/GlassPanel' import { stopPropagation } from '~/lib/dom' import type { PhotoAssetListItem } from '../../types' @@ -207,10 +208,10 @@ export function PhotoLibraryGrid({ if (!assets || assets.length === 0) { return ( -
+

当前没有图片资源

使用右上角的"上传图片"按钮可以为图库添加新的照片。

-
+
) }