調整設定隊伍流程並支援勝利分數設定
This commit is contained in:
64
src/App.tsx
64
src/App.tsx
@@ -17,11 +17,11 @@ import { HistoryPage } from './pages/HistoryPage'
|
||||
import { ScoreboardPage } from './pages/ScoreboardPage'
|
||||
import { TeamSelectionPage } from './pages/TeamSelectionPage'
|
||||
import type {
|
||||
ActiveMatchup,
|
||||
GroupTeam,
|
||||
HistoryUploadPayload,
|
||||
LoadStatus,
|
||||
MatchHistoryItem,
|
||||
Matchup,
|
||||
PointHistoryEntry,
|
||||
RoundGroup,
|
||||
ScoreSide,
|
||||
@@ -75,9 +75,9 @@ function App() {
|
||||
const [loadStatus, setLoadStatus] = useState<LoadStatus>('idle')
|
||||
const [loadMessage, setLoadMessage] = useState('')
|
||||
const [selectedGroupId, setSelectedGroupId] = useState<number | null>(null)
|
||||
const [matchup, setMatchup] = useState<Matchup>({
|
||||
leftTeamId: null,
|
||||
rightTeamId: null,
|
||||
const [activeMatchup, setActiveMatchup] = useState<ActiveMatchup>({
|
||||
leftTeam: null,
|
||||
rightTeam: null,
|
||||
})
|
||||
const [scoreState, setScoreState] = useState<ScoreState>(initialScoreState)
|
||||
const [scoreHistory, setScoreHistory] = useState<ScoreSnapshot[]>([])
|
||||
@@ -94,10 +94,8 @@ function App() {
|
||||
const parsedAreaA = useMemo(() => parseRoster(areaAInput), [areaAInput])
|
||||
const parsedAreaB = useMemo(() => parseRoster(areaBInput), [areaBInput])
|
||||
const selectedGroup = groups.find((group) => group.id === selectedGroupId) ?? null
|
||||
const leftTeam =
|
||||
selectedGroup?.teams.find((team) => team.id === matchup.leftTeamId) ?? null
|
||||
const rightTeam =
|
||||
selectedGroup?.teams.find((team) => team.id === matchup.rightTeamId) ?? null
|
||||
const leftTeam = activeMatchup.leftTeam
|
||||
const rightTeam = activeMatchup.rightTeam
|
||||
|
||||
useEffect(() => {
|
||||
window.localStorage.setItem(STORAGE_KEYS.targetDate, targetDate)
|
||||
@@ -132,19 +130,26 @@ function App() {
|
||||
const secondTeam = nextGroup?.teams[1] ?? null
|
||||
|
||||
setSelectedGroupId(nextGroup?.id ?? null)
|
||||
setMatchup({
|
||||
leftTeamId: firstTeam?.id ?? null,
|
||||
rightTeamId: secondTeam?.id ?? null,
|
||||
setActiveMatchup({
|
||||
leftTeam: firstTeam,
|
||||
rightTeam: secondTeam,
|
||||
})
|
||||
resetScoring()
|
||||
}
|
||||
|
||||
const applyMatchup = (leftTeamId: number, rightTeamId: number) => {
|
||||
setMatchup({
|
||||
leftTeamId,
|
||||
rightTeamId,
|
||||
const applyMatchup = (
|
||||
leftTeam: GroupTeam,
|
||||
rightTeam: GroupTeam,
|
||||
targetScore: number,
|
||||
) => {
|
||||
setActiveMatchup({
|
||||
leftTeam,
|
||||
rightTeam,
|
||||
})
|
||||
resetScoring({
|
||||
...initialScoreState,
|
||||
targetScore,
|
||||
})
|
||||
resetScoring()
|
||||
}
|
||||
|
||||
const loadGroupsFromDb = async () => {
|
||||
@@ -163,7 +168,7 @@ function App() {
|
||||
if (!record) {
|
||||
setGroups([])
|
||||
setSelectedGroupId(null)
|
||||
setMatchup({ leftTeamId: null, rightTeamId: null })
|
||||
setActiveMatchup({ leftTeam: null, rightTeam: null })
|
||||
setGroupSource('idle')
|
||||
setLoadStatus('empty')
|
||||
setLoadMessage('指定日期沒有資料,請改用手動配對。')
|
||||
@@ -181,7 +186,7 @@ function App() {
|
||||
} catch (error) {
|
||||
setGroups([])
|
||||
setSelectedGroupId(null)
|
||||
setMatchup({ leftTeamId: null, rightTeamId: null })
|
||||
setActiveMatchup({ leftTeam: null, rightTeam: null })
|
||||
setGroupSource('idle')
|
||||
setLoadStatus('error')
|
||||
setLoadMessage(error instanceof Error ? error.message : '讀取資料失敗。')
|
||||
@@ -192,7 +197,7 @@ function App() {
|
||||
if (parsedAreaA.length === 0 || parsedAreaB.length === 0) {
|
||||
setGroups([])
|
||||
setSelectedGroupId(null)
|
||||
setMatchup({ leftTeamId: null, rightTeamId: null })
|
||||
setActiveMatchup({ leftTeam: null, rightTeam: null })
|
||||
setGroupSource('idle')
|
||||
setLoadStatus('error')
|
||||
setLoadMessage('A 區與 B 區至少都要有 1 位成員。')
|
||||
@@ -212,9 +217,9 @@ function App() {
|
||||
return
|
||||
}
|
||||
|
||||
setMatchup((current) => ({
|
||||
leftTeamId: current.rightTeamId,
|
||||
rightTeamId: current.leftTeamId,
|
||||
setActiveMatchup((current) => ({
|
||||
leftTeam: current.rightTeam,
|
||||
rightTeam: current.leftTeam,
|
||||
}))
|
||||
|
||||
setScoreState((current) => ({
|
||||
@@ -487,13 +492,13 @@ function App() {
|
||||
path="/scoreboard"
|
||||
element={
|
||||
<ScoreboardPage
|
||||
currentSelectionOrder={getSelectionOrder(leftTeam, rightTeam)}
|
||||
finishDialogError={settlement.error}
|
||||
finishDialogOpen={settlement.open}
|
||||
finishDialogUploading={settlement.uploading}
|
||||
groupSource={groupSource}
|
||||
hasRecordedPoint={pointLog.length > 0}
|
||||
leftTeam={leftTeam}
|
||||
matchup={matchup}
|
||||
rightTeam={rightTeam}
|
||||
scoreState={scoreState}
|
||||
selectedGroup={selectedGroup}
|
||||
@@ -587,6 +592,19 @@ function formatPlayedAt(timestamp: number) {
|
||||
return new Date(timestamp * 1000).toLocaleString('zh-TW', { hour12: false })
|
||||
}
|
||||
|
||||
function getSelectionOrder(leftTeam: GroupTeam | null, rightTeam: GroupTeam | null) {
|
||||
if (!leftTeam || !rightTeam) {
|
||||
return []
|
||||
}
|
||||
|
||||
return [
|
||||
leftTeam.playerA,
|
||||
leftTeam.playerB,
|
||||
rightTeam.playerB,
|
||||
rightTeam.playerA,
|
||||
].filter((name) => name.trim().length > 0)
|
||||
}
|
||||
|
||||
function loadStoredText(storageKey: string, fallback: string) {
|
||||
const value = window.localStorage.getItem(storageKey)
|
||||
return value && value.trim() ? value : fallback
|
||||
|
||||
Reference in New Issue
Block a user