"use client"; import React from 'react'; import { get } from '@/api/request'; import { DashboardLayout } from "@/components/layout/dashboard-layout"; /** * Share (Invite) Page - Static UI with mocked data. * Sections: Invite Flow, My Invitation Code, Invite Records (with pagination) */ /** * 邀请记录项 */ type InviteRecord = { user_email: string; user_id: string; user_name: string; created_at: number; reward_status: number; activation_credits: number; first_payment_credits: number; }; /** * 分页信息 */ type PaginationInfo = { page: number; page_size: number; total: number; total_pages: number; has_next: boolean; has_prev: boolean; }; /** * 邀请记录API响应 */ type InviteRecordsResponse = { successful: boolean; code: number; message: string; data: { record_list: InviteRecord[]; pagination: PaginationInfo; }; }; const PAGE_SIZE = 10; /** * Format epoch ms using browser preferred language. * @param {number} epochMs - timestamp in milliseconds * @returns {string} - localized date time string */ function formatLocalTime(epochMs: number): string { try { const locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US'; const dtf = new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeStyle: 'medium', }); return dtf.format(new Date(epochMs)); } catch { return new Date(epochMs).toLocaleString(); } } /** * 从后端获取邀请记录 * @returns {Promise} */ async function fetchInviteRecords(): Promise { const res = await get('/api/user_fission/query_invite_record'); return res; } export default function SharePage(): JSX.Element { // Mocked data (to be replaced by real API integration later) const [inviteCode, setInviteCode] = React.useState(''); const [invitedCount, setInvitedCount] = React.useState(0); const [totalInviteCredits, setTotalInviteCredits] = React.useState(0); const [copyState, setCopyState] = React.useState<'idle' | 'copied' | 'error'>('idle'); const [records, setRecords] = React.useState([]); const [pagination, setPagination] = React.useState({ page: 1, page_size: 20, total: 0, total_pages: 1, has_next: false, has_prev: false }); const [pageIndex, setPageIndex] = React.useState(0); const [expandedRowIds, setExpandedRowIds] = React.useState>(() => new Set()); React.useEffect(() => { let mounted = true; // 并行发起所有请求,每个请求完成后立即处理 const fetchRecords = async () => { try { const response = await fetchInviteRecords(); if (!mounted) return; // 早期返回检查 if (response.successful) { setRecords(response.data.record_list); setPagination(response.data.pagination); } } catch (error) { if (mounted) { console.warn('Failed to fetch invite records:', error); } } }; const fetchStats = async () => { try { const res = await get('/api/user_fission/my_invite_stats'); if (!mounted) return; // 早期返回检查 const stats = res?.data ?? {}; if (typeof stats.total_invited === 'number') { setInvitedCount(stats.total_invited); } if (typeof stats.total_invite_credits === 'number') { setTotalInviteCredits(stats.total_invite_credits); } } catch (error) { if (mounted) { console.warn('Failed to fetch invite stats:', error); } } }; const fetchInviteCode = async () => { try { const res = await get('/api/user_fission/my_invite_code'); if (!mounted) return; // 早期返回检查 const code = res?.data?.invite_code ?? res?.data?.inviteCode ?? ''; if (typeof code === 'string') { setInviteCode(code); } } catch (error) { if (mounted) { console.warn('Failed to fetch invite code:', error); } } }; // 并行发起所有请求,每个请求完成后立即处理响应 fetchRecords(); fetchStats(); fetchInviteCode(); return () => { mounted = false; }; }, []); const totalPages = pagination.total_pages; const pagedRecords = records; // 后端已经分页,直接使用records const handleCopy = React.useCallback(async () => { try { await navigator.clipboard.writeText(location.origin + '/signup?inviteCode=' + inviteCode); setCopyState('copied'); window.setTimeout(() => setCopyState('idle'), 1600); } catch { setCopyState('error'); window.setTimeout(() => setCopyState('idle'), 1600); } }, [inviteCode]); const toggleRow = React.useCallback((id: string) => { setExpandedRowIds((prev: Set) => { const next = new Set(prev); if (next.has(id)) { next.delete(id); } else { next.add(id); } return next; }); }, []); return (

Invite Friends

Invite friends to join and earn rewards.

{/* Section 1: Invite Flow */}

Invitation Flow

  1. Step 1 Share

    Copy your invitation link and share it with friends.

  2. Step 2 Register

    Friends click the link and register directly.

  3. Step 3 Reward

    You both receive rewards after your friend activates their account.

{/* Section 2: My Invitation Link */}

My Invitation Link

{inviteCode ? `${'https://www.movieflow.ai'}/signup?inviteCode=${inviteCode}` : '-'}
{/* 右侧渐变遮挡 */}

Share this link. Your friends can register directly through it.

Total Credits {totalInviteCredits} All credits earned from invitations.
Invited Friends {invitedCount} Point details will be available soon.
{/* Section 3: Invite Records */}

Invite Records

{pagination.page} / {pagination.total_pages}
{pagedRecords.map((r: any) => { const inviteRewardDisplay = r.reward_status === 1 ? r.activation_credits : 0; const payRewardDisplay = r.first_payment_credits; const totalReward = inviteRewardDisplay + payRewardDisplay; const isExpanded = expandedRowIds.has(r.user_id); return ( {isExpanded && ( )} ); })}
Invited Username Registered At Reward
{r.user_name} {formatLocalTime(r.created_at * 1000)}
{totalReward}
{inviteRewardDisplay ? inviteRewardDisplay : 'Unverified'} Register Reward
{payRewardDisplay ? payRewardDisplay : 'Unpaid'} First Payment Reward
); }