Configure board deployment and backend proxy
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { useState } from 'react';
|
||||
import type { FormEvent } from 'react';
|
||||
import { CloudHeader } from '../components/CloudHeader';
|
||||
import { FloatingSearchDock } from '../components/FloatingSearchDock';
|
||||
import { WordCloudCanvas } from '../components/WordCloudCanvas';
|
||||
import { CloudLoadingState } from '../components/CloudLoadingState';
|
||||
import { CloudUnavailableState } from '../components/CloudUnavailableState';
|
||||
import { TitleFrost } from '../components/TitleFrost';
|
||||
import { useCloud } from '../hooks/useCloud';
|
||||
import { useWordCloudFocus } from '../hooks/useWordCloudFocus';
|
||||
import styles from './PersonalSearchPage.module.css';
|
||||
|
||||
interface PersonalSearchPageProps {
|
||||
cloudId: string;
|
||||
}
|
||||
|
||||
export function PersonalSearchPage({ cloudId }: PersonalSearchPageProps) {
|
||||
const cloudState = useCloud(cloudId);
|
||||
const cloud = cloudState.cloud;
|
||||
const [query, setQuery] = useState('');
|
||||
const [hasNotFound, setHasNotFound] = useState(false);
|
||||
const focus = useWordCloudFocus({ words: cloud?.words ?? [] });
|
||||
|
||||
if (cloudState.status === 'loading') {
|
||||
return <CloudLoadingState />;
|
||||
}
|
||||
|
||||
if (!cloud) {
|
||||
return <CloudUnavailableState />;
|
||||
}
|
||||
|
||||
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (!query.trim()) {
|
||||
setHasNotFound(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const found = focus.focusName(query);
|
||||
setHasNotFound(!found);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
focus.reset();
|
||||
setQuery('');
|
||||
setHasNotFound(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<main className={styles.page} data-cloud={cloud.id} aria-label="个人查找词云">
|
||||
<WordCloudCanvas
|
||||
words={cloud.words}
|
||||
phase={focus.phase}
|
||||
transform={focus.transform}
|
||||
activeIds={focus.activeIds}
|
||||
cloudRef={focus.cloudRef}
|
||||
onPointerDown={focus.handlePointerDown}
|
||||
onPointerMove={focus.handlePointerMove}
|
||||
onPointerUp={focus.handlePointerUp}
|
||||
onWheel={focus.handleWheel}
|
||||
onKeyDown={focus.handleKeyDown}
|
||||
sourceCanvas={cloud.sourceCanvas}
|
||||
sourceSvg={cloud.sourceSvg}
|
||||
viewport={focus.viewport}
|
||||
/>
|
||||
<TitleFrost />
|
||||
<CloudHeader
|
||||
eyebrow={cloud.eyebrow}
|
||||
title={cloud.title}
|
||||
subtitle={cloud.subtitle}
|
||||
dimmed={focus.phase !== 'idle'}
|
||||
layered
|
||||
/>
|
||||
<FloatingSearchDock
|
||||
name={query}
|
||||
status={focus.searchResult ? 'found' : hasNotFound ? 'not-found' : 'idle'}
|
||||
targetCount={focus.searchResult?.targets.length ?? 0}
|
||||
selectedTargetIndex={focus.searchResult?.selectedTargetIndex ?? 0}
|
||||
onChange={(name) => {
|
||||
setQuery(name);
|
||||
setHasNotFound(false);
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
onReset={handleReset}
|
||||
onSelectTarget={focus.selectTarget}
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user