[perf] Refactor component

This commit is contained in:
He
2026-06-16 19:14:39 +08:00
parent b86716e952
commit 89acd1f261
8 changed files with 137 additions and 165 deletions
+18 -25
View File
@@ -1,8 +1,8 @@
"use client" "use client"
import { NumberBall } from "@/components/number-ball" import { Matrix } from "@/components/matrix"
import { SettingsPanel } from "@/components/settings" import { SettingsPanel } from "@/components/settings"
import { ResultPanel } from "@/components/result" import { ResultPanel } from "@/components/group-result"
import { SingleModePanel } from "@/components/single-panel" import { SingleModePanel } from "@/components/single-panel"
import { TitleBar } from "@/components/title-bar" import { TitleBar } from "@/components/title-bar"
import { useRollCallLogic } from "@/components/logic" import { useRollCallLogic } from "@/components/logic"
@@ -74,18 +74,13 @@ export default function Page() {
)} )}
</div> </div>
<div className="flex-1 flex items-center justify-center overflow-auto scrollbar-thin p-3"> <div className="flex-1 flex items-center justify-center overflow-auto scrollbar-thin p-3">
<div className="flex flex-wrap gap-2 justify-center"> <Matrix
{Array.from({ length: typeof state.totalTasks === 'number' ? state.totalTasks : 0 }, (_, i) => i + 1).map((n) => ( total={state.totalTasks}
<NumberBall getBallState={actions.getBallState}
key={n} getBallColorIndex={actions.getBallColorIndex}
number={n} getBallDimmed={actions.getBallDimmed}
state={actions.getBallState(n)} size="xlarge"
colorIndex={actions.getBallColorIndex(n)} />
dimmed={actions.getBallDimmed(n)}
size="xlarge"
/>
))}
</div>
</div> </div>
</section> </section>
@@ -107,16 +102,14 @@ export default function Page() {
</span> </span>
)} )}
</div> </div>
<div className="flex flex-wrap gap-2 p-3 max-h-[40vh] overflow-y-auto scrollbar-thin"> <div className="p-3 max-h-[40vh] overflow-y-auto scrollbar-thin">
{Array.from({ length: typeof state.totalTasks === 'number' ? state.totalTasks : 0 }, (_, i) => i + 1).map((n) => ( <Matrix
<NumberBall total={state.totalTasks}
key={n} getBallState={actions.getBallState}
number={n} getBallColorIndex={actions.getBallColorIndex}
state={actions.getBallState(n)} getBallDimmed={actions.getBallDimmed}
colorIndex={actions.getBallColorIndex(n)} size="large"
size="large" />
/>
))}
</div> </div>
</section> </section>
@@ -135,7 +128,7 @@ export default function Page() {
)} )}
</div> </div>
<div className="flex-1 overflow-y-auto scrollbar-thin px-4 py-3"> <div className="flex-1 overflow-y-auto scrollbar-thin px-4 py-3">
<ResultPanel groups={state.groups} hasResult={state.hasResult} placeholder={state.placeholder} /> <ResultPanel groups={state.groups} hasResult={state.hasResult} />
</div> </div>
</section> </section>
</> </>
@@ -1,23 +1,19 @@
"use client" "use client"
import { COLORS } from "./logic" import { COLORS } from "@/components/logic"
interface ResultPanelProps { interface ResultPanelProps {
groups: { numbers: number[]; colorIndex: number }[] groups: { numbers: number[]; colorIndex: number }[]
hasResult: boolean hasResult: boolean
placeholder?: string
} }
export function ResultPanel({ groups, hasResult, placeholder }: ResultPanelProps) { export function ResultPanel({ groups, hasResult }: ResultPanelProps) {
if (!hasResult || groups.length === 0) { if (!hasResult || groups.length === 0) {
return ( return (
<div className="flex flex-col items-center justify-center h-full min-h-40 gap-3"> <div className="flex flex-col items-center justify-center h-full min-h-40 gap-3">
<div className="text-[10px] tracking-[0.2em] text-[#cdd2d8] font-mono uppercase"> <div className="text-[10px] tracking-[0.2em] text-[#cdd2d8] font-mono uppercase">
AWAITING INPUT AWAITING INPUT
</div> </div>
{placeholder && (
<div className="text-xs text-[#8a95a1] font-mono">{placeholder}</div>
)}
</div> </div>
) )
} }
@@ -49,6 +45,9 @@ export function ResultPanel({ groups, hasResult, placeholder }: ResultPanelProps
rows.push(currentRow) rows.push(currentRow)
} }
// 预先建立索引映射
const groupIndexMap = new Map(groups.map((g, i) => [g, i]))
return ( return (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
{rows.map((row, rowIdx) => ( {rows.map((row, rowIdx) => (
@@ -57,34 +56,31 @@ export function ResultPanel({ groups, hasResult, placeholder }: ResultPanelProps
className="flex gap-6 fui-slide-up" className="flex gap-6 fui-slide-up"
style={{ animationDelay: `${rowIdx * 40}ms` }} style={{ animationDelay: `${rowIdx * 40}ms` }}
> >
{row.map((group, idx) => { {row.map((group) => {
const sorted = [...group.numbers].sort((a, b) => a - b) const sorted = [...group.numbers].sort((a, b) => a - b)
const color = COLORS[group.colorIndex] const color = COLORS[group.colorIndex]
const globalIdx = groups.indexOf(group) const globalIdx = groupIndexMap.get(group)!
return ( return (
<div <div
key={globalIdx} key={globalIdx}
className="flex-1 min-w-0" className="flex-1 min-w-0"
> >
{/* Group label with color */} {/* Group label with color */}
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-3">
<div <div
className="w-2 h-2 rounded-full" className="w-3 h-3 rounded-full"
style={{ backgroundColor: color }} style={{ backgroundColor: color }}
/> />
<span className="text-xs font-mono uppercase tracking-[0.15em]" style={{ color }}> <span className="text-sm font-mono uppercase tracking-[0.15em]" style={{ color }}>
G{String(globalIdx + 1).padStart(2, "0")} G{String(globalIdx + 1).padStart(2, "0")}
</span> </span>
<span className="text-[10px] font-mono text-[#8a95a1]">
{String(group.numbers.length).padStart(2, "0")} P
</span>
</div> </div>
{/* Numbers with color */} {/* Numbers with color */}
<div className="flex flex-wrap gap-1.5"> <div className="flex flex-wrap gap-2">
{sorted.map((num) => ( {sorted.map((num) => (
<span <span
key={num} key={num}
className="min-w-8 h-8 px-1.5 flex items-center justify-center text-sm font-mono border fui-fadein" className="min-w-10 h-10 px-2 flex items-center justify-center text-base font-mono border fui-fadein"
style={{ style={{
borderColor: color + "40", borderColor: color + "40",
backgroundColor: color + "15", backgroundColor: color + "15",
+55 -83
View File
@@ -1,23 +1,25 @@
"use client" "use client"
import { useState, useCallback } from "react" import { useState, useCallback, useMemo } from "react"
export type Mode = "single" | "multi" export type Mode = "single" | "multi"
function getRandomDistinct(total: number, count: number, forbidSet: Set<number> = new Set()): number[] | null { function getRandomDistinct(total: number, count: number, forbidSet: Set<number> = new Set()): number[] | null {
if (count > total - forbidSet.size) return null // 构建可用数字数组
const result: number[] = [] const available: number[] = []
const selected = new Set<number>() for (let i = 1; i <= total; i++) {
let attempts = 0 if (!forbidSet.has(i)) available.push(i)
while (selected.size < count && attempts < 100000) {
const rand = Math.floor(Math.random() * total) + 1
if (!forbidSet.has(rand) && !selected.has(rand)) {
selected.add(rand)
result.push(rand)
}
attempts++
} }
return selected.size === count ? result : null
if (count > available.length) return null
// Fisher-Yates 洗牌算法
for (let i = available.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[available[i], available[j]] = [available[j], available[i]]
}
return available.slice(0, count)
} }
function generateGroups( function generateGroups(
@@ -54,9 +56,9 @@ function generateGroups(
export interface RollCallState { export interface RollCallState {
mode: Mode mode: Mode
totalTasks: number | string totalTasks: number
pickCount: number | string pickCount: number
rounds: number | string rounds: number
allowRepeat: boolean allowRepeat: boolean
// Multi mode // Multi mode
groups: { numbers: number[]; colorIndex: number }[] groups: { numbers: number[]; colorIndex: number }[]
@@ -72,14 +74,13 @@ export interface RollCallState {
// Common // Common
isRolling: boolean isRolling: boolean
errorMsg: string errorMsg: string
placeholder: string | undefined
} }
export interface RollCallActions { export interface RollCallActions {
setMode: (v: Mode) => void setMode: (v: Mode) => void
setTotalTasks: (v: number | string) => void setTotalTasks: (v: number) => void
setPickCount: (v: number | string) => void setPickCount: (v: number) => void
setRounds: (v: number | string) => void setRounds: (v: number) => void
setAllowRepeat: (v: boolean) => void setAllowRepeat: (v: boolean) => void
setSingleAllowRepeat: (v: boolean) => void setSingleAllowRepeat: (v: boolean) => void
handleRoll: () => void handleRoll: () => void
@@ -113,9 +114,9 @@ export const COLORS = [
export function useRollCallLogic(): [RollCallState, RollCallActions] { export function useRollCallLogic(): [RollCallState, RollCallActions] {
const [mode, setMode] = useState<Mode>("single") const [mode, setMode] = useState<Mode>("single")
const [totalTasks, setTotalTasks] = useState<number | string>(35) const [totalTasks, setTotalTasks] = useState<number>(35)
const [pickCount, setPickCount] = useState<number | string>(1) const [pickCount, setPickCount] = useState<number>(1)
const [rounds, setRounds] = useState<number | string>(1) const [rounds, setRounds] = useState<number>(1)
const [allowRepeat, setAllowRepeat] = useState(false) const [allowRepeat, setAllowRepeat] = useState(false)
// Multi mode state // Multi mode state
const [groups, setGroups] = useState<{ numbers: number[]; colorIndex: number }[]>([]) const [groups, setGroups] = useState<{ numbers: number[]; colorIndex: number }[]>([])
@@ -123,7 +124,6 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
const [usedAll, setUsedAll] = useState<Set<number>>(new Set()) const [usedAll, setUsedAll] = useState<Set<number>>(new Set())
const [hasResult, setHasResult] = useState(false) const [hasResult, setHasResult] = useState(false)
// Single mode state // Single mode state
const [selectedRecords, setSelectedRecords] = useState<{ number: number; colorIndex: number }[]>([])
const [singleBatches, setSingleBatches] = useState<{ numbers: number[]; colorIndex: number; batchNumber: number }[]>([]) const [singleBatches, setSingleBatches] = useState<{ numbers: number[]; colorIndex: number; batchNumber: number }[]>([])
const [singleHighlighted, setSingleHighlighted] = useState<number[]>([]) const [singleHighlighted, setSingleHighlighted] = useState<number[]>([])
const [isSingleComplete, setIsSingleComplete] = useState(false) const [isSingleComplete, setIsSingleComplete] = useState(false)
@@ -131,39 +131,38 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
// Common state // Common state
const [isRolling, setIsRolling] = useState(false) const [isRolling, setIsRolling] = useState(false)
const [errorMsg, setErrorMsg] = useState("") const [errorMsg, setErrorMsg] = useState("")
const [placeholder, setPlaceholder] = useState<string | undefined>()
// 从 singleBatches 计算 selectedRecords,消除数据冗余
const selectedRecords = useMemo(() => {
return singleBatches.flatMap(batch =>
batch.numbers.map(n => ({ number: n, colorIndex: batch.colorIndex }))
)
}, [singleBatches])
const resetAllState = useCallback(() => {
setHighlighted(new Set())
setUsedAll(new Set())
setGroups([])
setHasResult(false)
setSingleBatches([])
setSingleHighlighted([])
setIsSingleComplete(false)
setErrorMsg("")
}, [])
const handleModeChange = useCallback((newMode: Mode) => { const handleModeChange = useCallback((newMode: Mode) => {
setMode(newMode) setMode(newMode)
setHighlighted(new Set()) resetAllState()
setUsedAll(new Set()) }, [resetAllState])
setGroups([])
setHasResult(false)
setSelectedRecords([])
setSingleBatches([])
setSingleHighlighted([])
setIsSingleComplete(false)
setErrorMsg("")
setPlaceholder(undefined)
}, [])
const handleTotalChange = useCallback((v: number | string) => { const handleTotalChange = useCallback((v: number) => {
setTotalTasks(v) setTotalTasks(v)
setHighlighted(new Set()) resetAllState()
setUsedAll(new Set()) }, [resetAllState])
setGroups([])
setHasResult(false)
setSelectedRecords([])
setSingleBatches([])
setSingleHighlighted([])
setIsSingleComplete(false)
setErrorMsg("")
setPlaceholder(undefined)
}, [])
const handleRoundsChange = useCallback((v: number | string) => { const handleRoundsChange = useCallback((v: number) => {
setRounds(v) setRounds(v)
if (typeof v === 'number' && v < 2) setAllowRepeat(false) if (v < 2) setAllowRepeat(false)
setHighlighted(new Set()) setHighlighted(new Set())
setGroups([]) setGroups([])
setHasResult(false) setHasResult(false)
@@ -173,21 +172,11 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
const handleRoll = useCallback(async () => { const handleRoll = useCallback(async () => {
setErrorMsg("") setErrorMsg("")
// 检查空值
if (totalTasks === "" || pickCount === "" || rounds === "") {
setErrorMsg("请填写所有参数")
return
}
const total = totalTasks as number
const pick = pickCount as number
const roundCount = rounds as number
setIsRolling(true) setIsRolling(true)
await new Promise((r) => setTimeout(r, 240)) await new Promise((r) => setTimeout(r, 240))
const effectiveRepeat = roundCount < 2 ? false : allowRepeat const effectiveRepeat = rounds < 2 ? false : allowRepeat
const result = generateGroups(total, pick, roundCount, effectiveRepeat) const result = generateGroups(totalTasks, pickCount, rounds, effectiveRepeat)
if (!result.success) { if (!result.success) {
setErrorMsg(result.errorMsg) setErrorMsg(result.errorMsg)
@@ -205,37 +194,25 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
} }
setHasResult(true) setHasResult(true)
setIsRolling(false) setIsRolling(false)
setPlaceholder(undefined)
}, [totalTasks, pickCount, rounds, allowRepeat]) }, [totalTasks, pickCount, rounds, allowRepeat])
const handleSingleRoll = useCallback(async () => { const handleSingleRoll = useCallback(async () => {
setErrorMsg("") setErrorMsg("")
// 检查空值
if (totalTasks === "" || pickCount === "") {
setErrorMsg("请填写所有参数")
return
}
const total = totalTasks as number
const pick = pickCount as number
setIsRolling(true) setIsRolling(true)
setIsSingleComplete(false) setIsSingleComplete(false)
await new Promise((r) => setTimeout(r, 240)) await new Promise((r) => setTimeout(r, 240))
const usedNumbers = new Set(selectedRecords.map(r => r.number)) const usedNumbers = new Set(selectedRecords.map(r => r.number))
// 如果不允许重复,检查剩余人数 if (!singleAllowRepeat && pickCount > totalTasks - usedNumbers.size) {
if (!singleAllowRepeat && pick > total - usedNumbers.size) { setErrorMsg(`剩余可选人数不足 ${pickCount}`)
setErrorMsg(`剩余可选人数不足 ${pick}`)
setIsRolling(false) setIsRolling(false)
return return
} }
// 允许重复时,不需要检查人数
const forbidSet = singleAllowRepeat ? new Set<number>() : usedNumbers const forbidSet = singleAllowRepeat ? new Set<number>() : usedNumbers
const nums = getRandomDistinct(total, pick, forbidSet) const nums = getRandomDistinct(totalTasks, pickCount, forbidSet)
if (!nums) { if (!nums) {
setErrorMsg("抽取失败,人数不足") setErrorMsg("抽取失败,人数不足")
setIsRolling(false) setIsRolling(false)
@@ -244,10 +221,8 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
const newColorIndex = singleBatches.length % COLORS.length const newColorIndex = singleBatches.length % COLORS.length
const newBatchNumber = singleBatches.length + 1 const newBatchNumber = singleBatches.length + 1
const newRecords = [...selectedRecords, ...nums.map(n => ({ number: n, colorIndex: newColorIndex }))]
const newBatch = { numbers: nums, colorIndex: newColorIndex, batchNumber: newBatchNumber } const newBatch = { numbers: nums, colorIndex: newColorIndex, batchNumber: newBatchNumber }
setSelectedRecords(newRecords)
setSingleBatches([...singleBatches, newBatch]) setSingleBatches([...singleBatches, newBatch])
setSingleHighlighted(nums) setSingleHighlighted(nums)
setIsSingleComplete(true) setIsSingleComplete(true)
@@ -255,7 +230,6 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
}, [totalTasks, pickCount, selectedRecords, singleBatches, singleAllowRepeat]) }, [totalTasks, pickCount, selectedRecords, singleBatches, singleAllowRepeat])
const resetSingle = useCallback(() => { const resetSingle = useCallback(() => {
setSelectedRecords([])
setSingleBatches([]) setSingleBatches([])
setSingleHighlighted([]) setSingleHighlighted([])
setIsSingleComplete(false) setIsSingleComplete(false)
@@ -267,7 +241,6 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
setHighlighted(new Set()) setHighlighted(new Set())
setUsedAll(new Set()) setUsedAll(new Set())
setHasResult(false) setHasResult(false)
setPlaceholder(undefined)
}, []) }, [])
const getBallState = useCallback((n: number): "idle" | "highlighted" | "used" => { const getBallState = useCallback((n: number): "idle" | "highlighted" | "used" => {
@@ -322,13 +295,12 @@ export function useRollCallLogic(): [RollCallState, RollCallActions] {
singleAllowRepeat, singleAllowRepeat,
isRolling, isRolling,
errorMsg, errorMsg,
placeholder,
} }
const actions: RollCallActions = { const actions: RollCallActions = {
setMode: handleModeChange, setMode: handleModeChange,
setTotalTasks: handleTotalChange, setTotalTasks: handleTotalChange,
setPickCount: (v: number | string) => { setPickCount(v); setErrorMsg("") }, setPickCount: (v: number) => { setPickCount(v); setErrorMsg("") },
setRounds: handleRoundsChange, setRounds: handleRoundsChange,
setAllowRepeat, setAllowRepeat,
setSingleAllowRepeat, setSingleAllowRepeat,
+34
View File
@@ -0,0 +1,34 @@
"use client"
import { NumberBall } from "./number-ball"
interface MatrixProps {
total: number
getBallState: (n: number) => "idle" | "highlighted" | "used"
getBallColorIndex: (n: number) => number | undefined
getBallDimmed: (n: number) => boolean
size?: "normal" | "large" | "xlarge"
}
export function Matrix({
total,
getBallState,
getBallColorIndex,
getBallDimmed,
size = "normal"
}: MatrixProps) {
return (
<div className="flex flex-wrap gap-2 justify-center">
{Array.from({ length: total }, (_, i) => i + 1).map((n) => (
<NumberBall
key={n}
number={n}
state={getBallState(n)}
colorIndex={getBallColorIndex(n)}
dimmed={getBallDimmed(n)}
size={size}
/>
))}
</div>
)
}
+14 -37
View File
@@ -5,16 +5,16 @@ import type { Mode } from "@/components/logic"
interface SettingsPanelProps { interface SettingsPanelProps {
mode: Mode mode: Mode
totalTasks: number | string totalTasks: number
pickCount: number | string pickCount: number
rounds: number | string rounds: number
allowRepeat: boolean allowRepeat: boolean
singleAllowRepeat: boolean singleAllowRepeat: boolean
selectedRecords: { number: number; colorIndex: number }[] selectedRecords: { number: number; colorIndex: number }[]
onModeChange: (v: Mode) => void onModeChange: (v: Mode) => void
onTotalTasksChange: (v: number | string) => void onTotalTasksChange: (v: number) => void
onPickCountChange: (v: number | string) => void onPickCountChange: (v: number) => void
onRoundsChange: (v: number | string) => void onRoundsChange: (v: number) => void
onAllowRepeatChange: (v: boolean) => void onAllowRepeatChange: (v: boolean) => void
onSingleAllowRepeatChange: (v: boolean) => void onSingleAllowRepeatChange: (v: boolean) => void
onRoll: () => void onRoll: () => void
@@ -29,18 +29,13 @@ function FieldRow({
value, value,
onChange, onChange,
min = 1, min = 1,
error,
}: { }: {
label: string label: string
hint: string hint: string
value: number | string value: number
onChange: (v: number | string) => void onChange: (v: number) => void
min?: number min?: number
error?: string
}) { }) {
const displayValue = value === "" ? "" : value
const hasError = error && value === ""
return ( return (
<div className="flex items-center justify-between gap-4"> <div className="flex items-center justify-between gap-4">
<div className="min-w-0"> <div className="min-w-0">
@@ -49,13 +44,7 @@ function FieldRow({
</div> </div>
<div className="flex items-center gap-0 border border-[#e2e6ea] flex-shrink-0"> <div className="flex items-center gap-0 border border-[#e2e6ea] flex-shrink-0">
<button <button
onClick={() => { onClick={() => onChange(Math.max(min, value - 1))}
if (displayValue === "") {
onChange(min)
} else {
onChange(Math.max(min, (value as number) - 1))
}
}}
className="w-7 h-7 flex items-center justify-center text-[#8a95a1] hover:text-[#16191f] hover:bg-[#f1f3f5] transition-colors text-base leading-none" className="w-7 h-7 flex items-center justify-center text-[#8a95a1] hover:text-[#16191f] hover:bg-[#f1f3f5] transition-colors text-base leading-none"
aria-label={`减少${label}`} aria-label={`减少${label}`}
> >
@@ -63,33 +52,21 @@ function FieldRow({
</button> </button>
<input <input
type="number" type="number"
value={displayValue} value={value}
min={min} min={min}
onChange={(e) => { onChange={(e) => {
const inputValue = e.target.value const v = parseInt(e.target.value, 10)
if (inputValue === "") { if (!isNaN(v)) onChange(v)
onChange("")
} else {
const v = parseInt(inputValue, 10)
if (!isNaN(v)) onChange(v)
}
}} }}
className={cn( className={cn(
"w-12 h-7 text-center text-sm font-mono bg-[#f7f8fa]", "w-12 h-7 text-center text-sm font-mono bg-[#f7f8fa]",
"border-x border-[#e2e6ea]", "border-x border-[#e2e6ea]",
"focus:outline-none focus:bg-[#ffffff]", "focus:outline-none focus:bg-[#ffffff]",
"[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none", "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none"
hasError && "text-[#d92d20] border-[#d92d20]"
)} )}
/> />
<button <button
onClick={() => { onClick={() => onChange(value + 1)}
if (displayValue === "") {
onChange(min)
} else {
onChange((value as number) + 1)
}
}}
className="w-7 h-7 flex items-center justify-center text-[#8a95a1] hover:text-[#16191f] hover:bg-[#f1f3f5] transition-colors text-base leading-none" className="w-7 h-7 flex items-center justify-center text-[#8a95a1] hover:text-[#16191f] hover:bg-[#f1f3f5] transition-colors text-base leading-none"
aria-label={`增加${label}`} aria-label={`增加${label}`}
> >
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "roll-call", "name": "roll-call",
"version": "0.1.0", "version": "0.1.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "roll-call", "name": "roll-call",
"version": "0.1.0", "version": "0.1.1",
"dependencies": { "dependencies": {
"@base-ui/react": "^1.5.0", "@base-ui/react": "^1.5.0",
"@tauri-apps/api": "^2.11.0", "@tauri-apps/api": "^2.11.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "roll-call", "name": "roll-call",
"version": "0.1.0", "version": "0.1.1",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Roll Call", "productName": "Roll Call",
"version": "0.1.0", "version": "0.1.1",
"identifier": "dev.zhhe.rollcall", "identifier": "dev.zhhe.rollcall",
"build": { "build": {
"frontendDist": "../out", "frontendDist": "../out",