feat: add puzzle residence configuration and reflection progress logic

- Introduced `puzzleResidences.ts` to define puzzle residence configurations including properties like display name, position, and puzzle availability.
- Added `reflectionProgress.ts` to manage badge unlocking logic based on place completion, including functions to determine unlocked badges and video sources for scenes.
This commit is contained in:
zhongyidian committed 2026-04-27 11:49:30 +08:00
1 parent e0fa47d21a
commit f5f36f75b5
153 files changed
+3846 -2352

No files matched your search

@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'
import DragFill from './drag-fill'
import type { DragFillProps } from './drag-fill.types'
import { cn } from '@/lib/utils'
const meta: Meta<typeof DragFill> = {
@@ -47,6 +46,25 @@ const meta: Meta<typeof DragFill> = {
export default meta
type Story = StoryObj<typeof DragFill>
function ControlledDragFillStory() {
const [value, setValue] = useState<any[]>([])
return (
<div className="space-y-4">
<DragFill
options={['选项A', '选项B', '选项C']}
blanks={['空白1', '空白2']}
value={value}
onChange={setValue}
onSubmit={(results) => {
alert(`提交的结果: ${JSON.stringify(results)}`)
}}
/>
<div className="text-sm text-gray-600">当前填充: {JSON.stringify(value)}</div>
</div>
)
}
// 基础示例
export const Default: Story = {
args: {
@@ -80,23 +98,7 @@ export const WithObjects: Story = {
// 受控模式
export const Controlled: Story = {
render: () => {
const [value, setValue] = useState<any[]>([])
return (
<div className="space-y-4">
<DragFill
options={['选项A', '选项B', '选项C']}
blanks={['空白1', '空白2']}
value={value}
onChange={setValue}
onSubmit={(results) => {
alert(`提交的结果: ${JSON.stringify(results)}`)
}}
/>
<div className="text-sm text-gray-600">当前填充: {JSON.stringify(value)}</div>
</div>
)
},
render: () => <ControlledDragFillStory />,
}
// 允许重复选择
@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'
import MultipleChoice from './multiple-choice'
import type { MultipleChoiceProps } from './multiple-choice.types'
import { cn } from '@/lib/utils'
const meta: Meta<typeof MultipleChoice> = {
@@ -47,6 +46,26 @@ const meta: Meta<typeof MultipleChoice> = {
export default meta
type Story = StoryObj<typeof MultipleChoice>
function ControlledMultipleChoiceStory() {
const [values, setValues] = useState<string[]>([])
return (
<div className="space-y-4">
<MultipleChoice
options={['选项A', '选项B', '选项C', '选项D']}
value={values}
onChange={setValues}
onSubmit={(vals) => {
alert(`提交的值: ${vals.join(', ')}`)
}}
/>
<div className="text-sm text-gray-600">
当前选中: {values.length > 0 ? values.join(', ') : '未选择'}
</div>
</div>
)
}
// 基础示例
export const Default: Story = {
args: {
@@ -75,24 +94,7 @@ export const WithOptionObjects: Story = {
// 受控模式
export const Controlled: Story = {
render: () => {
const [values, setValues] = useState<string[]>([])
return (
<div className="space-y-4">
<MultipleChoice
options={['选项A', '选项B', '选项C', '选项D']}
value={values}
onChange={setValues}
onSubmit={(vals) => {
alert(`提交的值: ${vals.join(', ')}`)
}}
/>
<div className="text-sm text-gray-600">
当前选中: {values.length > 0 ? values.join(', ') : '未选择'}
</div>
</div>
)
},
render: () => <ControlledMultipleChoiceStory />,
}
// 限制最大选择数量
@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'
import SingleChoice from './single-choice'
import type { SingleChoiceProps } from './single-choice.types'
import { cn } from '@/lib/utils'
const meta: Meta<typeof SingleChoice> = {
@@ -39,6 +38,24 @@ const meta: Meta<typeof SingleChoice> = {
export default meta
type Story = StoryObj<typeof SingleChoice>
function ControlledSingleChoiceStory() {
const [value, setValue] = useState<string>('')
return (
<div className="space-y-4">
<SingleChoice
options={['选项A', '选项B', '选项C']}
value={value}
onChange={setValue}
onSubmit={(val) => {
alert(`提交的值: ${val}`)
}}
/>
<div className="text-sm text-gray-600">当前选中: {value || '未选择'}</div>
</div>
)
}
// 基础示例
export const Default: Story = {
args: {
@@ -66,22 +83,7 @@ export const WithOptionObjects: Story = {
// 受控模式
export const Controlled: Story = {
render: () => {
const [value, setValue] = useState<string>('')
return (
<div className="space-y-4">
<SingleChoice
options={['选项A', '选项B', '选项C']}
value={value}
onChange={setValue}
onSubmit={(val) => {
alert(`提交的值: ${val}`)
}}
/>
<div className="text-sm text-gray-600">当前选中: {value || '未选择'}</div>
</div>
)
},
render: () => <ControlledSingleChoiceStory />,
}
// 禁用状态