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