Desktop v2 screens: releases (store cards, stage stepper, rollout ring), submit checklist, TestFlight cards; listings as store pages with completeness, framed screenshots with issue badges, product cards, price matrix with gap shading; health tiles and issue cards, store-style review feed with rating distribution, growth funnel, readiness score with fix-first, tools grid, store-info sheet; settings, accounts, folders, dependencies and onboarding in the v2 language

This commit is contained in:
CRTkafa 2026-10-22 23:31:22 +08:00
parent ce939ee063
commit f131de9df2
47 changed files with 2309 additions and 927 deletions

View file

@ -5,7 +5,8 @@
import type { EditableResult, Project } from '../../api';
import { t } from '../../i18n';
import { ApplyPanel, EditBar, JsonField, TextField, useEdits } from '../../ui/Editor';
import { Card } from '../../ui/kit';
import { Section } from '../../ui/ds';
import '../../styles/testflight.css';
type O = Record<string, unknown>;
const obj = (v: unknown): O => (v && typeof v === 'object' && !Array.isArray(v) ? (v as O) : {});
@ -17,8 +18,8 @@ export function TestFlightEditor({ project, data, onSaved }: { project: Project;
const unsaved = e.count(project.id, 'testflight') ? t('ed.saveFirst') : null;
if (!data.apple) return null;
return (
<div className="stack" id="testflight-editor" style={{ gap: 16 }}>
<Card title={t('ed.tfTitle')} icon="edit" sub={t('ed.tfSub')}>
<div className="stack scr-testflight-ed" id="testflight-editor" style={{ gap: 16 }}>
<Section title={t('ed.tfTitle')} icon="edit" sub={t('ed.tfSub')}>
<div className="ed-langs">
{data.apple.map(l => (
<div className="ed-lang" key={l.lang}>
@ -35,14 +36,14 @@ export function TestFlightEditor({ project, data, onSaved }: { project: Project;
{typeof desc === 'string' && <TextField project={project} area="testflight" op={{ kind: 'config', path: 'apple.testflight.description' }} saved={desc} label={t('ed.betaDescriptionAll')} limit={4000} multiline rows={3} />}
<TextField project={project} area="testflight" op={{ kind: 'config', path: 'apple.testflight.reviewNotes' }} saved={typeof tf.reviewNotes === 'string' ? tf.reviewNotes : ''} label={t('ed.betaNotes')} limit={4000} multiline rows={3} />
<JsonField project={project} area="testflight" path="apple.testflight.groups" saved={tf.groups ?? null} label={t('ed.tfGroups')} rows={6} hint={t('ed.tfGroupsHint')} />
</Card>
</Section>
<EditBar project={project} area="testflight" data={data} files={[data.files.apple, data.files.config]} onSaved={onSaved} />
<Card title={t('ed.applyTitle')} icon="upload" sub={t('ed.applyTfSub')}>
<div className="act-grid">
<Section title={t('ed.applyTitle')} icon="upload" sub={t('ed.applyTfSub')}>
<div className="act-grid tf-apply">
<ApplyPanel project={project} method="apple.testflight_info" label={t('ed.applyTfInfo')} done={t('ai.pushed')} blocked={unsaved} />
<ApplyPanel project={project} method="apple.testflight_groups" label={t('tf.groupsSync')} done={t('tf.groupsSynced')} blocked={unsaved} />
</div>
</Card>
</Section>
</div>
);
}