feat: add settings page

This commit is contained in:
YunYouJun
2023-08-20 02:28:00 +08:00
parent 95ce2c4dac
commit 98123b0039
14 changed files with 1638 additions and 971 deletions

View 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>

View 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>

View 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>

View File

@@ -1,10 +1,16 @@
import { acceptHMRUpdate, defineStore } from 'pinia' import { acceptHMRUpdate, defineStore } from 'pinia'
import { useStorage } from '@vueuse/core'
import { defaultSettings } from '~/utils/settings'
import { namespace } from '~/constants'
export const useAppStore = defineStore('app', () => { export const useAppStore = defineStore('app', () => {
const deferredPrompt = ref<Event | any>() const deferredPrompt = ref<Event | any>()
const settings = useStorage(`${namespace}:settings`, defaultSettings)
return { return {
deferredPrompt, deferredPrompt,
settings,
} }
}) })

View File

@@ -17,6 +17,7 @@ export type SearchMode = 'survival' | 'loose' | 'strict'
export const useRecipeStore = defineStore('recipe', () => { export const useRecipeStore = defineStore('recipe', () => {
const gtm = useGtm() const gtm = useGtm()
const { settings } = useAppStore()
/** /**
* 搜索关键字 * 搜索关键字
@@ -24,10 +25,10 @@ export const useRecipeStore = defineStore('recipe', () => {
const keyword = ref('') const keyword = ref('')
// can not exported // 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 curTools = ref(new Set<string>())
const curTool = useStorage(`${namespace}:tool`, '') const curTool = settings.keepLocalData ? useStorage(`${namespace}:tool`, '') : ref('')
const curMode = useStorage<SearchMode>(`${namespace}:mode`, 'loose') const curMode = settings.keepLocalData ? useStorage<SearchMode>(`${namespace}:mode`, 'loose') : ref<SearchMode>('loose')
const selectedStuff = computed(() => Array.from(curStuff.value)) const selectedStuff = computed(() => Array.from(curStuff.value))
// const selectedTools = computed(() => Array.from(curTools.value)) // const selectedTools = computed(() => Array.from(curTools.value))

View File

@@ -1,5 +1,5 @@
<template> <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 /> <slot />
<DarkToggle absolute right-5 top-5 /> <DarkToggle absolute right-5 top-5 />
<TheBottomMenu fixed bottom-0 left-0 right-0 /> <TheBottomMenu fixed bottom-0 left-0 right-0 />

View File

@@ -48,7 +48,7 @@ export default defineNuxtConfig({
}, },
prerender: { prerender: {
crawlLinks: false, crawlLinks: false,
routes: ['/'], routes: ['/', '/random', 'help', '/user'],
ignore: ['/hi'], ignore: ['/hi'],
}, },
}, },

View File

@@ -24,21 +24,21 @@
"vue-about-me": "^1.2.7" "vue-about-me": "^1.2.7"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.40.0", "@antfu/eslint-config": "^0.40.2",
"@headlessui/vue": "^1.7.15", "@headlessui/vue": "^1.7.16",
"@iconify-json/carbon": "^1.1.18", "@iconify-json/carbon": "^1.1.19",
"@iconify-json/fe": "^1.1.6", "@iconify-json/fe": "^1.1.7",
"@iconify-json/gg": "^1.1.5", "@iconify-json/gg": "^1.1.6",
"@iconify-json/ic": "^1.1.13", "@iconify-json/ic": "^1.1.14",
"@iconify-json/mdi": "^1.1.53", "@iconify-json/mdi": "^1.1.54",
"@iconify-json/ri": "^1.1.11", "@iconify-json/ri": "^1.1.12",
"@iconify-json/twemoji": "^1.1.11", "@iconify-json/twemoji": "^1.1.12",
"@nuxt/devtools": "^0.7.4", "@nuxt/devtools": "^0.8.0",
"@nuxtjs/color-mode": "^3.3.0", "@nuxtjs/color-mode": "^3.3.0",
"@pinia/nuxt": "^0.4.11", "@pinia/nuxt": "^0.4.11",
"@pinia/testing": "^0.1.3", "@pinia/testing": "^0.1.3",
"@unocss/eslint-config": "^0.54.1", "@unocss/eslint-config": "^0.55.2",
"@unocss/nuxt": "^0.54.1", "@unocss/nuxt": "^0.55.2",
"@vite-pwa/nuxt": "^0.1.0", "@vite-pwa/nuxt": "^0.1.0",
"@vue/test-utils": "^2.4.1", "@vue/test-utils": "^2.4.1",
"@vueuse/nuxt": "^10.3.0", "@vueuse/nuxt": "^10.3.0",
@@ -47,17 +47,17 @@
"consola": "^3.2.3", "consola": "^3.2.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dexie": "^3.2.4", "dexie": "^3.2.4",
"eslint": "^8.46.0", "eslint": "^8.47.0",
"fake-indexeddb": "^4.0.2", "fake-indexeddb": "^4.0.2",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"nuxt": "^3.6.5", "nuxt": "^3.6.5",
"pinia": "^2.1.6", "pinia": "^2.1.6",
"sass": "^1.64.2", "sass": "^1.66.1",
"star-markdown-css": "^0.4.2", "star-markdown-css": "^0.4.2",
"tsx": "^3.12.7", "tsx": "^3.12.7",
"typescript": "^5.1.6", "typescript": "^5.1.6",
"unocss": "^0.54.1", "unocss": "^0.55.2",
"vitest": "^0.34.1", "vitest": "^0.34.2",
"vue-tsc": "^1.8.8" "vue-tsc": "^1.8.8"
} }
} }

View File

@@ -9,6 +9,10 @@
<FeedbackActions /> <FeedbackActions />
<div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left> <div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left>
<FAQItem title="未来计划?">
计划增加新功能如自定义菜谱与使用其他用户分享的菜谱
</FAQItem>
<FAQItem title="什么是模式?"> <FAQItem title="什么是模式?">
<ul> <ul>
<li><b>模糊匹配</b>展示所有含当前选中任意食材的菜谱</li> <li><b>模糊匹配</b>展示所有含当前选中任意食材的菜谱</li>
@@ -80,6 +84,87 @@
</li> </li>
</ol> </ol>
</FAQItem> </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>
</div> </div>
<BaseFooter mt-4 /> <BaseFooter mt-4 />

View File

@@ -1,90 +1,34 @@
<script lang="ts" setup>
import { links } from '~/constants'
const app = useAppStore()
</script>
<template> <template>
<div> <div>
<CommonHeader> <CommonHeader>
我的 我的
</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> <YlfForm>
<FAQItem :default-open="true" title="关于"> <YlfFormItem label="离开网页后保留选中数据">
<div text-left> <YlfSwitch v-model="app.settings.keepLocalData" />
<ul> </YlfFormItem>
<li> <YlfFormItem label="更多设置,敬请期待" />
它诞生于 2022 4 时值疫情风控期间希望能帮助期间的伙伴根据现有食材寻找到合适的菜谱故原名隔离食用手册 </YlfForm>
</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="关于我"> <YlfForm>
<div text-left> <YlfFormItem label="关于" to="/help" />
我的个人微信公众号云游君会分享一些生活和写的<a href="https://sponsors.yunyoujun.cn/projects" target="_blank"> </YlfForm>
小玩具们
</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 /> <BaseFooter mt-4 />

2260
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,11 +2,23 @@
--c-primary: #5fc178; --c-primary: #5fc178;
--c-text: #333; --c-text: #333;
--c-bg: #fff; --c-bg: white;
--c-bg-alt: #f9fbfd;
} }
.dark { .dark {
--c-text: #fafafa; --c-text: #fafafa;
--c-bg: #121212; --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;
} }

View File

@@ -8,11 +8,10 @@ body,
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: var(--c-bg);
} }
html.dark {
background: #121212;
}
input:focus { input:focus {
outline: none; outline: none;

10
utils/settings.ts Normal file
View File

@@ -0,0 +1,10 @@
export interface UserSettings {
/**
* 保留本地数据
*/
keepLocalData: boolean
}
export const defaultSettings: UserSettings = {
keepLocalData: true,
}