feat: add settings page
This commit is contained in:
23
components/common/YlfForm.vue
Normal file
23
components/common/YlfForm.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="ylf-form" flex="~ col">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.ylf-form {
|
||||
background-color: var(--ylf-c-bg-alt);
|
||||
|
||||
border-top: 1px solid var(--ylf-c-border);
|
||||
border-bottom: 1px solid var(--ylf-c-border);
|
||||
|
||||
margin: 10px 0;
|
||||
|
||||
.ylf-form-item {
|
||||
border-bottom: 1px solid var(--ylf-c-border);
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
33
components/common/YlfFormItem.vue
Normal file
33
components/common/YlfFormItem.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script lang="ts" setup>
|
||||
import { NuxtLink } from '#components'
|
||||
|
||||
defineProps<{
|
||||
icon?: string
|
||||
label?: string
|
||||
/**
|
||||
* Router link
|
||||
*/
|
||||
to?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="to ? NuxtLink : 'div'"
|
||||
:to="to"
|
||||
class="ylf-form-item"
|
||||
w-full flex cursor-pointer items-center justify-between p-3
|
||||
hover:bg-gray-100
|
||||
dark:hover:bg-dark-400
|
||||
>
|
||||
<div v-if="label" class="text-md" inline-flex items-center justify-center>
|
||||
<div v-if="icon" :class="icon" mr-2 inline-flex />
|
||||
<span>{{ label }}</span>
|
||||
</div>
|
||||
<div inline-flex>
|
||||
<slot>
|
||||
<div v-if="to" i-ri-arrow-right-s-line />
|
||||
</slot>
|
||||
</div>
|
||||
</component>
|
||||
</template>
|
||||
28
components/common/YlfSwitch.vue
Normal file
28
components/common/YlfSwitch.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts" setup>
|
||||
import { Switch } from '@headlessui/vue'
|
||||
|
||||
defineProps<{
|
||||
modelValue: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
function updateModelValue(value: boolean) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Switch
|
||||
:model-value="modelValue"
|
||||
:class="modelValue ? 'bg-blue-600' : 'bg-gray'"
|
||||
class="relative h-6 w-11 inline-flex shrink-0 cursor-pointer border-2 border-transparent rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
|
||||
@update:model-value="updateModelValue"
|
||||
>
|
||||
<span class="sr-only">Use setting</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
:class="modelValue ? 'translate-x-5' : 'translate-x-0'"
|
||||
class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out"
|
||||
/>
|
||||
</Switch>
|
||||
</template>
|
||||
@@ -1,10 +1,16 @@
|
||||
import { acceptHMRUpdate, defineStore } from 'pinia'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { defaultSettings } from '~/utils/settings'
|
||||
import { namespace } from '~/constants'
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
const deferredPrompt = ref<Event | any>()
|
||||
const settings = useStorage(`${namespace}:settings`, defaultSettings)
|
||||
|
||||
return {
|
||||
deferredPrompt,
|
||||
|
||||
settings,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export type SearchMode = 'survival' | 'loose' | 'strict'
|
||||
|
||||
export const useRecipeStore = defineStore('recipe', () => {
|
||||
const gtm = useGtm()
|
||||
const { settings } = useAppStore()
|
||||
|
||||
/**
|
||||
* 搜索关键字
|
||||
@@ -24,10 +25,10 @@ export const useRecipeStore = defineStore('recipe', () => {
|
||||
const keyword = ref('')
|
||||
|
||||
// can not exported
|
||||
const curStuff = useStorage(`${namespace}:stuff`, new Set<string>())
|
||||
const curStuff = settings.keepLocalData ? useStorage(`${namespace}:stuff`, new Set<string>()) : ref(new Set<string>())
|
||||
// const curTools = ref(new Set<string>())
|
||||
const curTool = useStorage(`${namespace}:tool`, '')
|
||||
const curMode = useStorage<SearchMode>(`${namespace}:mode`, 'loose')
|
||||
const curTool = settings.keepLocalData ? useStorage(`${namespace}:tool`, '') : ref('')
|
||||
const curMode = settings.keepLocalData ? useStorage<SearchMode>(`${namespace}:mode`, 'loose') : ref<SearchMode>('loose')
|
||||
|
||||
const selectedStuff = computed(() => Array.from(curStuff.value))
|
||||
// const selectedTools = computed(() => Array.from(curTools.value))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<main class="text-center text-gray-700 dark:text-gray-200" p="x-2 t-8 b-15">
|
||||
<main class="text-center text-gray-700 dark:text-gray-200" p="t-8 b-15">
|
||||
<slot />
|
||||
<DarkToggle absolute right-5 top-5 />
|
||||
<TheBottomMenu fixed bottom-0 left-0 right-0 />
|
||||
|
||||
@@ -48,7 +48,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
prerender: {
|
||||
crawlLinks: false,
|
||||
routes: ['/'],
|
||||
routes: ['/', '/random', 'help', '/user'],
|
||||
ignore: ['/hi'],
|
||||
},
|
||||
},
|
||||
|
||||
32
package.json
32
package.json
@@ -24,21 +24,21 @@
|
||||
"vue-about-me": "^1.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.40.0",
|
||||
"@headlessui/vue": "^1.7.15",
|
||||
"@iconify-json/carbon": "^1.1.18",
|
||||
"@iconify-json/fe": "^1.1.6",
|
||||
"@iconify-json/gg": "^1.1.5",
|
||||
"@iconify-json/ic": "^1.1.13",
|
||||
"@iconify-json/mdi": "^1.1.53",
|
||||
"@iconify-json/ri": "^1.1.11",
|
||||
"@iconify-json/twemoji": "^1.1.11",
|
||||
"@nuxt/devtools": "^0.7.4",
|
||||
"@antfu/eslint-config": "^0.40.2",
|
||||
"@headlessui/vue": "^1.7.16",
|
||||
"@iconify-json/carbon": "^1.1.19",
|
||||
"@iconify-json/fe": "^1.1.7",
|
||||
"@iconify-json/gg": "^1.1.6",
|
||||
"@iconify-json/ic": "^1.1.14",
|
||||
"@iconify-json/mdi": "^1.1.54",
|
||||
"@iconify-json/ri": "^1.1.12",
|
||||
"@iconify-json/twemoji": "^1.1.12",
|
||||
"@nuxt/devtools": "^0.8.0",
|
||||
"@nuxtjs/color-mode": "^3.3.0",
|
||||
"@pinia/nuxt": "^0.4.11",
|
||||
"@pinia/testing": "^0.1.3",
|
||||
"@unocss/eslint-config": "^0.54.1",
|
||||
"@unocss/nuxt": "^0.54.1",
|
||||
"@unocss/eslint-config": "^0.55.2",
|
||||
"@unocss/nuxt": "^0.55.2",
|
||||
"@vite-pwa/nuxt": "^0.1.0",
|
||||
"@vue/test-utils": "^2.4.1",
|
||||
"@vueuse/nuxt": "^10.3.0",
|
||||
@@ -47,17 +47,17 @@
|
||||
"consola": "^3.2.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"dexie": "^3.2.4",
|
||||
"eslint": "^8.46.0",
|
||||
"eslint": "^8.47.0",
|
||||
"fake-indexeddb": "^4.0.2",
|
||||
"jsdom": "^22.1.0",
|
||||
"nuxt": "^3.6.5",
|
||||
"pinia": "^2.1.6",
|
||||
"sass": "^1.64.2",
|
||||
"sass": "^1.66.1",
|
||||
"star-markdown-css": "^0.4.2",
|
||||
"tsx": "^3.12.7",
|
||||
"typescript": "^5.1.6",
|
||||
"unocss": "^0.54.1",
|
||||
"vitest": "^0.34.1",
|
||||
"unocss": "^0.55.2",
|
||||
"vitest": "^0.34.2",
|
||||
"vue-tsc": "^1.8.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
<FeedbackActions />
|
||||
|
||||
<div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left>
|
||||
<FAQItem title="未来计划?">
|
||||
计划增加新功能,如自定义菜谱,与使用其他用户分享的菜谱。
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="什么是模式?">
|
||||
<ul>
|
||||
<li><b>模糊匹配</b>:展示所有含当前选中任意食材的菜谱</li>
|
||||
@@ -80,6 +84,87 @@
|
||||
</li>
|
||||
</ol>
|
||||
</FAQItem>
|
||||
|
||||
<hr h="1" my="4" bg-black>
|
||||
|
||||
<FAQItem :default-open="true" title="关于">
|
||||
<div text-left>
|
||||
<ul>
|
||||
<li>
|
||||
它诞生于 2022 年 4 月,时值疫情风控期间,希望能帮助期间的伙伴根据现有食材寻找到合适的菜谱。故原名「隔离食用手册」。
|
||||
</li>
|
||||
<li>
|
||||
如今那个时期已离我们远去,故去掉「隔离」二字。但也很高兴能在这里继续与你相遇,希望它能继续发光发热,在日常生活中帮助到大家。
|
||||
</li>
|
||||
<li>
|
||||
<div class="inline-flex items-center justify-center">
|
||||
代码仓库:<a class="inline-flex items-center justify-center" href="https://github.com/YunYouJun/cook" target="_blank">
|
||||
<div m="r-1" i-ri-github-line inline-flex />YunYouJun/cook</a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="inline-flex items-center justify-center">
|
||||
菜谱视频来源:
|
||||
<a class="inline-flex items-center text-sm text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS" target="_blank">
|
||||
<div m="r-1" i-ri-bilibili-line inline-flex />
|
||||
<span class="inline-flex">隔离食用手册大全</span>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="关于我">
|
||||
<div text-left>
|
||||
我的个人微信公众号「云游君」,会分享一些生活和写的<a href="https://sponsors.yunyoujun.cn/projects" target="_blank">
|
||||
小玩具们
|
||||
</a>。
|
||||
|
||||
<a inline-flex py-4 href="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg" target="_blank">
|
||||
<img src="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg">
|
||||
</a>
|
||||
</div>
|
||||
<AboutMe />
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="致谢">
|
||||
<p>
|
||||
感谢以下小伙伴为本项目提供的数据支持和 QA !
|
||||
</p>
|
||||
|
||||
<ul mt-2 text-left text-sm>
|
||||
<li>
|
||||
<a href="https://weibo.com/runny" target="_blank">Runny</a>
|
||||
</li>
|
||||
<li>
|
||||
山竹太凉
|
||||
</li>
|
||||
<li>
|
||||
leo
|
||||
</li>
|
||||
<li>
|
||||
麒麟
|
||||
</li>
|
||||
<li>
|
||||
晴方啾
|
||||
</li>
|
||||
<li>
|
||||
课代表阿伟
|
||||
</li>
|
||||
</ul>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="赞助者们">
|
||||
<div>
|
||||
感谢至今以来所有的<a href="https://afdian.net/a/yunyoujun" class="text-purple" target="_blank">赞助者</a>们,你们的支持是我持续维护和开发新项目的动力!
|
||||
</div>
|
||||
<div pt-2>
|
||||
<a href="https://sponsors.yunyoujun.cn" target="_blank">
|
||||
<img src="https://sponsors.yunyoujun.cn/sponsors.svg">
|
||||
</a>
|
||||
</div>
|
||||
</FAQItem>
|
||||
</div>
|
||||
</div>
|
||||
<BaseFooter mt-4 />
|
||||
|
||||
102
pages/user.vue
102
pages/user.vue
@@ -1,90 +1,34 @@
|
||||
<script lang="ts" setup>
|
||||
import { links } from '~/constants'
|
||||
|
||||
const app = useAppStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<CommonHeader>
|
||||
我的
|
||||
</CommonHeader>
|
||||
|
||||
<FeedbackActions />
|
||||
<div
|
||||
class="mx-auto max-w-md w-full"
|
||||
text-left
|
||||
>
|
||||
<YlfForm>
|
||||
<YlfFormItem icon="i-ri-feedback-line" label="立即反馈" :to="links.feedback" target="_blank" />
|
||||
<YlfFormItem icon="i-ri-mail-send-line" label="立即投稿" :to="links.contribute" target="_blank" />
|
||||
</YlfForm>
|
||||
|
||||
<div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left>
|
||||
<FAQItem :default-open="true" title="关于">
|
||||
<div text-left>
|
||||
<ul>
|
||||
<li>
|
||||
它诞生于 2022 年 4 月,时值疫情风控期间,希望能帮助期间的伙伴根据现有食材寻找到合适的菜谱。故原名「隔离食用手册」。
|
||||
</li>
|
||||
<li>
|
||||
如今那个时期已离我们远去,故去掉「隔离」二字。但也很高兴能在这里继续与你相遇,希望它能继续发光发热,在日常生活中帮助到大家。
|
||||
</li>
|
||||
<li>
|
||||
<div class="inline-flex items-center justify-center">
|
||||
代码仓库:<a class="inline-flex items-center justify-center" href="https://github.com/YunYouJun/cook" target="_blank">
|
||||
<div m="r-1" i-ri-github-line inline-flex />YunYouJun/cook</a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="inline-flex items-center justify-center">
|
||||
菜谱视频来源:
|
||||
<a class="inline-flex items-center text-sm text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS" target="_blank">
|
||||
<div m="r-1" i-ri-bilibili-line inline-flex />
|
||||
<span class="inline-flex">隔离食用手册大全</span>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</FAQItem>
|
||||
<YlfForm>
|
||||
<YlfFormItem label="离开网页后保留选中数据">
|
||||
<YlfSwitch v-model="app.settings.keepLocalData" />
|
||||
</YlfFormItem>
|
||||
<YlfFormItem label="更多设置,敬请期待" />
|
||||
</YlfForm>
|
||||
|
||||
<FAQItem title="关于我">
|
||||
<div text-left>
|
||||
我的个人微信公众号「云游君」,会分享一些生活和写的<a href="https://sponsors.yunyoujun.cn/projects" target="_blank">
|
||||
小玩具们
|
||||
</a>。
|
||||
|
||||
<a inline-flex py-4 href="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg" target="_blank">
|
||||
<img src="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg">
|
||||
</a>
|
||||
</div>
|
||||
<AboutMe />
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="致谢">
|
||||
<p>
|
||||
感谢以下小伙伴为本项目提供的数据支持和 QA !
|
||||
</p>
|
||||
|
||||
<ul mt-2 text-left text-sm>
|
||||
<li>
|
||||
<a href="https://weibo.com/runny" target="_blank">Runny</a>
|
||||
</li>
|
||||
<li>
|
||||
山竹太凉
|
||||
</li>
|
||||
<li>
|
||||
leo
|
||||
</li>
|
||||
<li>
|
||||
麒麟
|
||||
</li>
|
||||
<li>
|
||||
晴方啾
|
||||
</li>
|
||||
<li>
|
||||
课代表阿伟
|
||||
</li>
|
||||
</ul>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="赞助者们">
|
||||
<div>
|
||||
感谢至今以来所有的<a href="https://afdian.net/a/yunyoujun" class="text-purple" target="_blank">赞助者</a>们,你们的支持是我持续维护和开发新项目的动力!
|
||||
</div>
|
||||
<div pt-2>
|
||||
<a href="https://sponsors.yunyoujun.cn" target="_blank">
|
||||
<img src="https://sponsors.yunyoujun.cn/sponsors.svg">
|
||||
</a>
|
||||
</div>
|
||||
</FAQItem>
|
||||
<YlfForm>
|
||||
<YlfFormItem label="关于" to="/help" />
|
||||
</YlfForm>
|
||||
</div>
|
||||
|
||||
<BaseFooter mt-4 />
|
||||
|
||||
2260
pnpm-lock.yaml
generated
2260
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,23 @@
|
||||
--c-primary: #5fc178;
|
||||
--c-text: #333;
|
||||
|
||||
--c-bg: #fff;
|
||||
--c-bg: white;
|
||||
--c-bg-alt: #f9fbfd;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--c-text: #fafafa;
|
||||
|
||||
--c-bg: #121212;
|
||||
--c-bg-alt: #333;
|
||||
}
|
||||
|
||||
// ylf
|
||||
:root {
|
||||
--ylf-c-bg-alt: var(--c-bg-alt);
|
||||
--ylf-c-border: #eaeaea;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--ylf-c-border: #666;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,10 @@ body,
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background: var(--c-bg);
|
||||
}
|
||||
|
||||
html.dark {
|
||||
background: #121212;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
|
||||
10
utils/settings.ts
Normal file
10
utils/settings.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export interface UserSettings {
|
||||
/**
|
||||
* 保留本地数据
|
||||
*/
|
||||
keepLocalData: boolean
|
||||
}
|
||||
|
||||
export const defaultSettings: UserSettings = {
|
||||
keepLocalData: true,
|
||||
}
|
||||
Reference in New Issue
Block a user