[feat] Support empty numeric inputs & UI improvements for real app
This commit is contained in:
@@ -86,9 +86,15 @@
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground font-mono antialiased;
|
||||
/* 禁用右键菜单 */
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
html {
|
||||
@apply bg-background;
|
||||
/* 禁用触摸移动 */
|
||||
overscroll-behavior: none;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-7
@@ -6,11 +6,23 @@ import { ResultPanel } from "@/components/result"
|
||||
import { SingleModePanel } from "@/components/single-panel"
|
||||
import { TitleBar } from "@/components/title-bar"
|
||||
import { useRollCallLogic } from "@/components/logic"
|
||||
import { useEffect } from "react"
|
||||
|
||||
export default function Page() {
|
||||
const [state, actions] = useRollCallLogic()
|
||||
const isSingleMode = state.mode === "single"
|
||||
|
||||
// 禁用右键菜单
|
||||
useEffect(() => {
|
||||
const handleContextMenu = (e: MouseEvent) => {
|
||||
e.preventDefault()
|
||||
}
|
||||
document.addEventListener('contextmenu', handleContextMenu)
|
||||
return () => {
|
||||
document.removeEventListener('contextmenu', handleContextMenu)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="h-screen w-full bg-[#0f141a] text-[#16191f] font-mono flex flex-col overflow-hidden">
|
||||
{/* Custom title bar */}
|
||||
@@ -61,16 +73,16 @@ export default function Page() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 flex items-center justify-center overflow-auto scrollbar-thin p-8">
|
||||
<div className="flex flex-wrap gap-2 justify-center max-w-2xl">
|
||||
{Array.from({ length: state.totalTasks }, (_, i) => i + 1).map((n) => (
|
||||
<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)}
|
||||
size="large"
|
||||
size="xlarge"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -95,8 +107,8 @@ export default function Page() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2 p-4 max-h-[40vh] overflow-y-auto scrollbar-thin">
|
||||
{Array.from({ length: state.totalTasks }, (_, i) => i + 1).map((n) => (
|
||||
<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}
|
||||
@@ -110,7 +122,7 @@ export default function Page() {
|
||||
|
||||
{/* Group mode result panel */}
|
||||
<section className="flex flex-col flex-1 min-h-0">
|
||||
<div className="flex items-center gap-3 px-5 py-2.5 border-b border-[#e2e6ea] flex-shrink-0">
|
||||
<div className="flex items-center gap-3 px-4 py-2.5 border-b border-[#e2e6ea] flex-shrink-0">
|
||||
<span className="text-[10px] tracking-[0.2em] uppercase text-[#8a95a1]">OUTPUT</span>
|
||||
<span className="flex-1 h-px bg-[#e2e6ea]" />
|
||||
{state.hasResult && state.groups.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user