feat: integrate pixel teacher presence and resilient classroom preview
This commit is contained in:
1 parent
12d800ec51
commit
7951cca700
60 files changed
+3313
-180
No files matched your search
@@ -0,0 +1,32 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { normalizeAppError } from '@/lib/error-model';
|
||||
import { codingRecovery, type CodingRecoveryAction } from '../../../shared/coding-recovery';
|
||||
|
||||
export function CodingRecoveryCard({ code, work, onRecovery }: {
|
||||
code?: string;
|
||||
work: boolean;
|
||||
onRecovery(action: CodingRecoveryAction, work: boolean): Promise<void> | void;
|
||||
}) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [retryCode, setRetryCode] = useState<string>();
|
||||
const [retryFailed, setRetryFailed] = useState(false);
|
||||
const flight = useRef(false);
|
||||
const recovery = codingRecovery(retryCode ?? code, work);
|
||||
return <div role="status" className="rounded-xl border border-brand/15 bg-brand/5 p-4 text-sm" data-testid="coding-recovery-card">
|
||||
<p className="font-medium">{work ? '作品还没有打开' : '这一步需要再接着做'}</p>
|
||||
<p className="mt-1 text-muted-foreground">{retryFailed ? '暂时还没连接上。可以稍后再试,已输入的内容会保留。' : recovery.message}</p>
|
||||
<Button className="mt-3" size="sm" variant="outline" disabled={busy} onClick={async () => {
|
||||
if (flight.current) return;
|
||||
flight.current = true;
|
||||
setBusy(true);
|
||||
setRetryFailed(false);
|
||||
try { await onRecovery(recovery.action, work); }
|
||||
catch (error) {
|
||||
const failure = normalizeAppError(error);
|
||||
setRetryCode(typeof failure.details?.backendCode === 'string' ? failure.details.backendCode : failure.code);
|
||||
setRetryFailed(failure.code !== 'AUTH_INVALID');
|
||||
} finally { flight.current = false; setBusy(false); }
|
||||
}}>{busy ? '正在接着处理…' : recovery.label}</Button>
|
||||
</div>;
|
||||
}
|
||||
Reference in new issue
Block a user