Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37bab9269c | ||
|
|
44f9b40ee5 | ||
|
|
4ddd5ac2d2 | ||
|
|
9df47e977e | ||
|
|
5fb76f24dc | ||
|
|
014f129b8e | ||
|
|
2949c45839 | ||
|
|
81586158d5 | ||
|
|
bfb6ea3e14 | ||
|
|
7d26f9ba84 | ||
|
|
9f12401922 | ||
|
|
69c689df67 | ||
|
|
8ca8c4aac8 |
17
.vscode/settings.json
vendored
17
.vscode/settings.json
vendored
@@ -1,5 +1,20 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": ["Vitesse", "Vite", "unocss", "vitest", "vueuse", "pinia", "demi", "antfu", "iconify", "intlify", "vitejs", "unplugin", "pnpm"],
|
"cSpell.words": [
|
||||||
|
"antfu",
|
||||||
|
"demi",
|
||||||
|
"iconify",
|
||||||
|
"intlify",
|
||||||
|
"nuxi",
|
||||||
|
"pinia",
|
||||||
|
"pnpm",
|
||||||
|
"unocss",
|
||||||
|
"unplugin",
|
||||||
|
"Vite",
|
||||||
|
"vitejs",
|
||||||
|
"Vitesse",
|
||||||
|
"vitest",
|
||||||
|
"vueuse"
|
||||||
|
],
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.css": "postcss"
|
"*.css": "postcss"
|
||||||
},
|
},
|
||||||
|
|||||||
105
components/common/SearchRecipe.vue
Normal file
105
components/common/SearchRecipe.vue
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Dialog, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'
|
||||||
|
|
||||||
|
import { db } from '~/utils/db'
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
isOpen.value = false
|
||||||
|
}
|
||||||
|
function openModal() {
|
||||||
|
isOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyword = ref('')
|
||||||
|
async function getFilterRecipes(keyword: string) {
|
||||||
|
return db.recipes.filter((recipe) => {
|
||||||
|
return recipe.name.includes(keyword)
|
||||||
|
}).toArray()
|
||||||
|
}
|
||||||
|
const filteredRecipes = computedAsync(async () => {
|
||||||
|
return await getFilterRecipes(keyword.value)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<YlfIconButton
|
||||||
|
absolute right-3 top-5
|
||||||
|
class="icon-btn hover:text-yellow-400 !outline-none"
|
||||||
|
text-xl
|
||||||
|
title="切换" @click="openModal"
|
||||||
|
>
|
||||||
|
<div i="ri-search-line" />
|
||||||
|
</YlfIconButton>
|
||||||
|
|
||||||
|
<TransitionRoot appear :show="isOpen" as="template">
|
||||||
|
<Dialog as="div" class="relative z-10" @close="closeModal">
|
||||||
|
<TransitionChild
|
||||||
|
as="template"
|
||||||
|
enter="duration-300 ease-out"
|
||||||
|
enter-from="opacity-0"
|
||||||
|
enter-to="opacity-100"
|
||||||
|
leave="duration-200 ease-in"
|
||||||
|
leave-from="opacity-100"
|
||||||
|
leave-to="opacity-0"
|
||||||
|
>
|
||||||
|
<div class="fixed inset-0 bg-black/10" />
|
||||||
|
</TransitionChild>
|
||||||
|
|
||||||
|
<div class="fixed inset-0 overflow-y-auto">
|
||||||
|
<div
|
||||||
|
class="h-full flex justify-center text-center"
|
||||||
|
>
|
||||||
|
<TransitionChild
|
||||||
|
as="template"
|
||||||
|
enter="duration-300 ease-out"
|
||||||
|
enter-from="opacity-0 scale-95"
|
||||||
|
enter-to="opacity-100 scale-100"
|
||||||
|
leave="duration-200 ease-in"
|
||||||
|
leave-from="opacity-100 scale-100"
|
||||||
|
leave-to="opacity-0 scale-95"
|
||||||
|
>
|
||||||
|
<DialogPanel
|
||||||
|
class="h-full max-w-xl w-full transform overflow-hidden bg-white p-4 text-left align-middle shadow-xl transition-all dark:bg-dark-600"
|
||||||
|
md="rounded-2xl"
|
||||||
|
overflow="auto"
|
||||||
|
flex="~ col"
|
||||||
|
>
|
||||||
|
<DialogTitle
|
||||||
|
as="h3"
|
||||||
|
class="flex items-center justify-center text-lg font-medium leading-6"
|
||||||
|
>
|
||||||
|
<div relative inline-flex flex="grow">
|
||||||
|
<div
|
||||||
|
i-ri-search-line
|
||||||
|
class="absolute left-3 top-2 cursor-pointer text-gray-400"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="keyword"
|
||||||
|
type="text"
|
||||||
|
class="w-full rounded-full bg-transparent text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 placeholder-gray-400"
|
||||||
|
border="~ rounded-full gray-300 op-50 focus:border-blue-500"
|
||||||
|
placeholder="搜索菜谱"
|
||||||
|
autofocus py-2 pl-10 pr-3
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="keyword" i-ri-close-line
|
||||||
|
class="absolute right-3 top-2 cursor-pointer text-gray-400"
|
||||||
|
@click="keyword = ''"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div op="70" ml-2 inline-flex cursor-pointer text-base @click="closeModal">
|
||||||
|
取消
|
||||||
|
</div>
|
||||||
|
</DialogTitle>
|
||||||
|
<div flex="~ col grow" overflow="auto" class="mt-2" text-xs>
|
||||||
|
<DishTag v-for="item, i in filteredRecipes" :key="i" :dish="item" />
|
||||||
|
</div>
|
||||||
|
</DialogPanel>
|
||||||
|
</TransitionChild>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</TransitionRoot>
|
||||||
|
</template>
|
||||||
@@ -3,6 +3,7 @@ import type { DbRecipeItem } from '~/utils/db'
|
|||||||
import { tools } from '~/data/food'
|
import { tools } from '~/data/food'
|
||||||
import type { RecipeItem } from '~/types'
|
import type { RecipeItem } from '~/types'
|
||||||
import { getEmojisFromStuff } from '~/utils'
|
import { getEmojisFromStuff } from '~/utils'
|
||||||
|
import { recipeHistories } from '~/composables/store/history'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
dish: RecipeItem | DbRecipeItem
|
dish: RecipeItem | DbRecipeItem
|
||||||
@@ -10,16 +11,21 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const gtm = useGtm()
|
const gtm = useGtm()
|
||||||
|
|
||||||
function triggerGtm(val: string) {
|
function triggerGtm(dish: RecipeItem) {
|
||||||
|
recipeHistories.value.push({
|
||||||
|
recipe: dish,
|
||||||
|
time: Date.now(),
|
||||||
|
})
|
||||||
|
|
||||||
gtm?.trackEvent({
|
gtm?.trackEvent({
|
||||||
event: 'click',
|
event: 'click',
|
||||||
category: `dish_${val}`,
|
category: `dish_${dish.name}`,
|
||||||
action: 'click_recipe',
|
action: 'click_recipe',
|
||||||
label: '跳转菜谱',
|
label: '跳转菜谱',
|
||||||
})
|
})
|
||||||
gtm?.trackEvent({
|
gtm?.trackEvent({
|
||||||
event: 'click_dish',
|
event: 'click_dish',
|
||||||
action: val,
|
action: dish.name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +40,7 @@ const dishLabel = computed(() => {
|
|||||||
:href="dish.link || `https://www.bilibili.com/video/${dish.bv}`" target="_blank" class="dish-tag rounded tag" p="x-2"
|
:href="dish.link || `https://www.bilibili.com/video/${dish.bv}`" target="_blank" class="dish-tag rounded tag" p="x-2"
|
||||||
border="~ blue-200 dark:blue-800"
|
border="~ blue-200 dark:blue-800"
|
||||||
bg="blue-300 opacity-20"
|
bg="blue-300 opacity-20"
|
||||||
@click="triggerGtm(dish.name)"
|
@click="triggerGtm(dish)"
|
||||||
>
|
>
|
||||||
<span m="r-1" class="inline-flex items-center justify-center" text="sm blue-700 dark:blue-200">
|
<span m="r-1" class="inline-flex items-center justify-center" text="sm blue-700 dark:blue-200">
|
||||||
{{ dishLabel }}
|
{{ dishLabel }}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ defineProps<{
|
|||||||
:is="to ? NuxtLink : 'div'"
|
:is="to ? NuxtLink : 'div'"
|
||||||
:to="to"
|
:to="to"
|
||||||
class="ylf-form-item"
|
class="ylf-form-item"
|
||||||
w-full flex cursor-pointer items-center justify-between p-3
|
w-full flex cursor-pointer items-center justify-between p-2
|
||||||
hover:bg-gray-100
|
hover:bg-gray-100
|
||||||
dark:hover:bg-dark-400
|
dark:hover:bg-dark-400
|
||||||
>
|
>
|
||||||
<div v-if="label" class="text-md" inline-flex items-center justify-center>
|
<div v-if="label" class="text-sm" inline-flex items-center justify-center>
|
||||||
<div v-if="icon" :class="icon" mr-2 inline-flex />
|
<div v-if="icon" :class="icon" mr-2 inline-flex />
|
||||||
<span>{{ label }}</span>
|
<span>{{ label }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
22
components/ylf/YlfIconItem.vue
Normal file
22
components/ylf/YlfIconItem.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
defineProps<{
|
||||||
|
icon: string
|
||||||
|
label: string
|
||||||
|
to: string
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NuxtLink
|
||||||
|
:to="to"
|
||||||
|
flex="~ col"
|
||||||
|
border="~ solid dark:$ylf-c-border"
|
||||||
|
bg="$ylf-c-bg-alt"
|
||||||
|
class="inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium decoration-none hover-bg-gray-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 dark:hover:bg-dark-400"
|
||||||
|
>
|
||||||
|
<div :class="icon" inline-flex text-lg />
|
||||||
|
<div mt-2 inline-flex text-xs>
|
||||||
|
{{ label }}
|
||||||
|
</div>
|
||||||
|
</NuxtLink>
|
||||||
|
</template>
|
||||||
10
composables/store/history.ts
Normal file
10
composables/store/history.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { useStorage } from '@vueuse/core'
|
||||||
|
import { namespace } from '~/constants'
|
||||||
|
import type { RecipeItem } from '~/types'
|
||||||
|
|
||||||
|
export interface RecipeHistoryItem {
|
||||||
|
recipe: RecipeItem
|
||||||
|
time: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const recipeHistories = useStorage<RecipeHistoryItem[]>(`${namespace}:history`, [])
|
||||||
@@ -78,8 +78,6 @@ export const useRecipeStore = defineStore('recipe', () => {
|
|||||||
async function searchRecipes() {
|
async function searchRecipes() {
|
||||||
isSearching.value = true
|
isSearching.value = true
|
||||||
let result: RecipeItem[] = []
|
let result: RecipeItem[] = []
|
||||||
if (keyword.value)
|
|
||||||
result = await db.recipes.filter(item => item.name.includes(keyword.value)).toArray()
|
|
||||||
|
|
||||||
if (curMode.value === 'strict') {
|
if (curMode.value === 'strict') {
|
||||||
result = await db.recipes.filter((item) => {
|
result = await db.recipes.filter((item) => {
|
||||||
@@ -116,14 +114,18 @@ export const useRecipeStore = defineStore('recipe', () => {
|
|||||||
}).toArray()
|
}).toArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyword.value)
|
||||||
|
result = result.filter(item => item.name.includes(keyword.value))
|
||||||
|
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认严格模式
|
// 默认严格模式
|
||||||
const displayedRecipe = ref<RecipeItem[]>([])
|
const displayedRecipe = ref<RecipeItem[]>([])
|
||||||
watch([keyword, curStuff, curTool, curMode], async () => {
|
// fix curStuff watch
|
||||||
displayedRecipe.value = await searchRecipes()
|
watch(() => [keyword.value, selectedStuff.value, curTool.value, curMode.value], async () => {
|
||||||
|
displayedRecipe.value = [...(await searchRecipes())]
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ export const appName = '食用手册'
|
|||||||
export const appDescription = '好的,今天我们来做菜!'
|
export const appDescription = '好的,今天我们来做菜!'
|
||||||
|
|
||||||
export const namespace = 'cook'
|
export const namespace = 'cook'
|
||||||
export const lastDbUpdated = '2022-07-27 03:05:02'
|
export const lastDbUpdated = '2023-11-11 19:51:02'
|
||||||
|
|
||||||
export * from './links'
|
export * from './links'
|
||||||
|
|||||||
@@ -217,7 +217,6 @@ BBQ烟熏手撕猪肉,猪肉,BV1DV411x7SH,复杂,,烤,烤箱,
|
|||||||
微波炉版照烧鸡腿饭,米、鸡肉、胡萝卜、花菜,BV16Z4y1V774,,,,微波炉,
|
微波炉版照烧鸡腿饭,米、鸡肉、胡萝卜、花菜,BV16Z4y1V774,,,,微波炉,
|
||||||
微波炉版蒸蛋羹,鸡蛋,BV19T4y1D7Zd,,,,微波炉,
|
微波炉版蒸蛋羹,鸡蛋,BV19T4y1D7Zd,,,,微波炉,
|
||||||
微波炉版煮米饭,米,BV193411W7nb,,,,微波炉,
|
微波炉版煮米饭,米,BV193411W7nb,,,,微波炉,
|
||||||
豉油鸡翅,鸡肉,BV1vz4y1d775,普通,茶餐厅,煮,一口大锅,
|
|
||||||
水煮肉片,猪肉、芹菜、莴笋,BV1ZZ4y1379N,普通,川菜,炒,一口大锅,
|
水煮肉片,猪肉、芹菜、莴笋,BV1ZZ4y1379N,普通,川菜,炒,一口大锅,
|
||||||
脆口黄瓜,黄瓜,BV1Tb4y1X7ow,简单,脆口,凉拌,一口大锅,
|
脆口黄瓜,黄瓜,BV1Tb4y1X7ow,简单,脆口,凉拌,一口大锅,
|
||||||
白萝卜汤,白萝卜,BV1HJ411L7xA,简单,单一食材,煮,一口大锅,
|
白萝卜汤,白萝卜,BV1HJ411L7xA,简单,单一食材,煮,一口大锅,
|
||||||
@@ -297,7 +296,7 @@ BBQ烟熏手撕猪肉,猪肉,BV1DV411x7SH,复杂,,烤,烤箱,
|
|||||||
名古屋鸡翅,鸡肉,BV1ET4y1A7Xd,普通,日式,炸,一口大锅,
|
名古屋鸡翅,鸡肉,BV1ET4y1A7Xd,普通,日式,炸,一口大锅,
|
||||||
日式炖白萝,白萝卜,BV17b411B7H1,简单,日式,炖,一口大锅,
|
日式炖白萝,白萝卜,BV17b411B7H1,简单,日式,炖,一口大锅,
|
||||||
炸虾天妇罗,虾,BV1e5411t7LY,困难,日式,炸,一口大锅,
|
炸虾天妇罗,虾,BV1e5411t7LY,困难,日式,炸,一口大锅,
|
||||||
可乐饼,土豆、洋葱、肉、鸡蛋,BV1yW411Q7sa,普通,日式菜,炸,一口大锅,
|
可乐饼,土豆、洋葱、肉、鸡蛋,BV17x411U75q,普通,日式菜,炸,一口大锅,
|
||||||
清炒莴笋丝,莴笋、胡萝卜,BV1qK411H7RL,简单,爽口,炒,一口大锅,
|
清炒莴笋丝,莴笋、胡萝卜,BV1qK411H7RL,简单,爽口,炒,一口大锅,
|
||||||
莴笋泡菜,莴笋,BV1h741127rS,简单,爽口,泡菜,一口大锅,
|
莴笋泡菜,莴笋,BV1h741127rS,简单,爽口,泡菜,一口大锅,
|
||||||
口蘑汤,菌菇,BV1e64y1h776,简单,汤,煎、炖,一口大锅,
|
口蘑汤,菌菇,BV1e64y1h776,简单,汤,煎、炖,一口大锅,
|
||||||
@@ -598,3 +597,4 @@ biangbiang面,面食,BV1844y157GL,简单,,油泼,一口大锅,
|
|||||||
电饭煲番茄牛肉焖饭,番茄、牛肉、米,BV1Bv411C7X3,普通,,,一口大锅、电饭煲,
|
电饭煲番茄牛肉焖饭,番茄、牛肉、米,BV1Bv411C7X3,普通,,,一口大锅、电饭煲,
|
||||||
电饭煲排骨土豆焖饭,猪肉、土豆、米,BV1Bv411C7X3,普通,,,一口大锅、电饭煲,
|
电饭煲排骨土豆焖饭,猪肉、土豆、米,BV1Bv411C7X3,普通,,,一口大锅、电饭煲,
|
||||||
米布丁,米、鸡蛋,BV1hr4y1k7A5,简单,,,一口大锅、电饭煲,
|
米布丁,米、鸡蛋,BV1hr4y1k7A5,简单,,,一口大锅、电饭煲,
|
||||||
|
麻婆豆腐,豆腐,BV1it4y1X75m,简单,,,一口大锅,
|
||||||
|
|||||||
|
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@ const route = useRoute()
|
|||||||
<main class="text-center text-gray-700 dark:text-gray-200" p="t-5 b-15">
|
<main class="text-center text-gray-700 dark:text-gray-200" p="t-5 b-15">
|
||||||
<div flex items-center justify-between>
|
<div flex items-center justify-between>
|
||||||
<BackBtn ml-3 />
|
<BackBtn ml-3 />
|
||||||
<h2 flex items-center justify-center text-lg>
|
<h2 flex items-center justify-center text-lg font="bold">
|
||||||
{{ route.meta.title }}
|
{{ route.meta.title }}
|
||||||
</h2>
|
</h2>
|
||||||
<DarkToggle mr-3 />
|
<DarkToggle mr-3 />
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<main class="cook-main text-center text-gray-700 dark:text-gray-200" p="t-8 b-$cook-bottom-menu-height">
|
<main class="cook-main text-center text-gray-700 dark:text-gray-200" p="t-8 b-$cook-bottom-menu-height">
|
||||||
<slot />
|
<slot />
|
||||||
<DarkToggle absolute right-3 top-5 />
|
<DarkToggle absolute left-3 top-5 />
|
||||||
|
<SearchRecipe />
|
||||||
<TheBottomMenu fixed bottom-0 left-0 right-0 />
|
<TheBottomMenu fixed bottom-0 left-0 right-0 />
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
23
package.json
23
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.1.8",
|
"version": "1.2.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@8.10.2",
|
"packageManager": "pnpm@8.10.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run convert && cross-env VITE_APP_BUILD_TIME=$(date +%s) nuxi build",
|
"build": "npm run convert && cross-env VITE_APP_BUILD_TIME=$(date +%s) nuxi build",
|
||||||
|
"build:static": "npm run convert && cross-env VITE_APP_BUILD_TIME=$(date +%s) nuxi generate",
|
||||||
"convert": "tsx scripts/convert.ts",
|
"convert": "tsx scripts/convert.ts",
|
||||||
"dev": "cross-env VITE_APP_BUILD_TIME=$(date +%s) nuxi dev --host",
|
"dev": "cross-env VITE_APP_BUILD_TIME=$(date +%s) nuxi dev --host",
|
||||||
"dev:pwa": "VITE_PLUGIN_PWA=true nuxi dev",
|
"dev:pwa": "VITE_PLUGIN_PWA=true nuxi dev",
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
"typecheck": "vue-tsc --noEmit"
|
"typecheck": "vue-tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
"vue-about-me": "^1.2.7"
|
"vue-about-me": "^1.2.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -34,17 +36,18 @@
|
|||||||
"@iconify-json/mdi": "^1.1.55",
|
"@iconify-json/mdi": "^1.1.55",
|
||||||
"@iconify-json/ri": "^1.1.12",
|
"@iconify-json/ri": "^1.1.12",
|
||||||
"@iconify-json/twemoji": "^1.1.12",
|
"@iconify-json/twemoji": "^1.1.12",
|
||||||
"@nuxt/devtools": "^1.0.0",
|
"@nuxt/devtools": "^1.0.1",
|
||||||
"@nuxtjs/color-mode": "^3.3.0",
|
"@nuxtjs/color-mode": "^3.3.0",
|
||||||
"@pinia/nuxt": "^0.5.1",
|
"@pinia/nuxt": "^0.5.1",
|
||||||
"@pinia/testing": "^0.1.3",
|
"@pinia/testing": "^0.1.3",
|
||||||
"@unocss/eslint-config": "^0.57.2",
|
"@unocss/eslint-config": "^0.57.3",
|
||||||
"@unocss/nuxt": "^0.57.2",
|
"@unocss/nuxt": "^0.57.3",
|
||||||
"@vite-pwa/nuxt": "^0.1.1",
|
"@vite-pwa/nuxt": "^0.2.1",
|
||||||
"@vue/test-utils": "^2.4.1",
|
"@vue/test-utils": "^2.4.1",
|
||||||
"@vueuse/nuxt": "^10.5.0",
|
"@vueuse/nuxt": "^10.6.0",
|
||||||
"@yunlefun/vue": "0.0.8-beta.4",
|
"@yunlefun/vue": "0.0.8-beta.4",
|
||||||
"@zadigetvoltaire/nuxt-gtm": "^0.0.13",
|
"@zadigetvoltaire/nuxt-gtm": "^0.0.13",
|
||||||
|
"bumpp": "^9.2.0",
|
||||||
"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",
|
||||||
@@ -52,14 +55,14 @@
|
|||||||
"fake-indexeddb": "^5.0.1",
|
"fake-indexeddb": "^5.0.1",
|
||||||
"happy-dom": "^12.10.3",
|
"happy-dom": "^12.10.3",
|
||||||
"jsdom": "^22.1.0",
|
"jsdom": "^22.1.0",
|
||||||
"nuxt": "^3.8.0",
|
"nuxt": "^3.8.1",
|
||||||
"nuxt-vitest": "^0.11.2",
|
"nuxt-vitest": "^0.11.3",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.69.5",
|
"sass": "^1.69.5",
|
||||||
"star-markdown-css": "^0.4.2",
|
"star-markdown-css": "^0.4.2",
|
||||||
"tsx": "^3.14.0",
|
"tsx": "^4.1.1",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"unocss": "^0.57.2",
|
"unocss": "^0.57.3",
|
||||||
"vitest": "^0.34.6",
|
"vitest": "^0.34.6",
|
||||||
"vue-tsc": "^1.8.22"
|
"vue-tsc": "^1.8.22"
|
||||||
}
|
}
|
||||||
|
|||||||
12
pages/recipes/collect.vue
Normal file
12
pages/recipes/collect.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'child',
|
||||||
|
title: '我的收藏',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
施工中...
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
38
pages/recipes/history.vue
Normal file
38
pages/recipes/history.vue
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { recipeHistories } from '~/composables/store/history'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'child',
|
||||||
|
title: '历史记录',
|
||||||
|
})
|
||||||
|
|
||||||
|
// todo
|
||||||
|
// clear one history
|
||||||
|
function clearAllHistory() {
|
||||||
|
recipeHistories.value = []
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div pt-2>
|
||||||
|
<div
|
||||||
|
text="blue-900 dark:blue-200"
|
||||||
|
bg="blue-300 op-20 hover:(blue-800 op-20) dark:hover:(blue-200 op-20)"
|
||||||
|
class="inline-flex items-center justify-center border border-transparent rounded-md px-4 py-2 text-sm font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500"
|
||||||
|
@click="clearAllHistory"
|
||||||
|
>
|
||||||
|
<div i-ri-eraser-line />
|
||||||
|
<span class="ml-1">清空记录</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div flex="~ col">
|
||||||
|
<div v-for="history in recipeHistories" :key="history.recipe.name" mt-2>
|
||||||
|
<StapleTag :active="false">
|
||||||
|
{{ dayjs(history.time).format('YYYY-MM-DD HH:mm:ss') }}
|
||||||
|
</StapleTag>
|
||||||
|
<DishTag :dish="history.recipe" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -13,6 +13,12 @@ import { links } from '~/constants'
|
|||||||
px-2
|
px-2
|
||||||
text-left
|
text-left
|
||||||
>
|
>
|
||||||
|
<div mt-2 gap="3" grid="~ cols-3">
|
||||||
|
<YlfIconItem to="/recipes/history" icon="i-ri-history-line" label="历史记录" />
|
||||||
|
<YlfIconItem to="/recipes/collect" icon="i-ri-star-line" label="我的收藏" />
|
||||||
|
<YlfIconItem to="/cookbooks" icon="i-ri-article-line" label="自定义菜谱" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<YlfForm>
|
<YlfForm>
|
||||||
<YlfFormItem icon="i-ri-feedback-line" label="立即反馈" :to="links.feedback" target="_blank" />
|
<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" />
|
<YlfFormItem icon="i-ri-mail-send-line" label="立即投稿" :to="links.contribute" target="_blank" />
|
||||||
@@ -22,9 +28,9 @@ import { links } from '~/constants'
|
|||||||
<YlfFormItem icon="i-ri-settings-line" label="设置" to="/settings" />
|
<YlfFormItem icon="i-ri-settings-line" label="设置" to="/settings" />
|
||||||
</YlfForm>
|
</YlfForm>
|
||||||
|
|
||||||
<YlfForm>
|
<!-- <YlfForm>
|
||||||
<YlfFormItem icon="i-ri-article-line" label="自定义菜谱" to="/cookbooks/" />
|
<YlfFormItem icon="i-ri-article-line" label="自定义菜谱 TODO" to="/cookbooks/" />
|
||||||
</YlfForm>
|
</YlfForm> -->
|
||||||
|
|
||||||
<YlfForm>
|
<YlfForm>
|
||||||
<YlfFormItem icon="i-ri-question-line" label="帮助" to="/help" />
|
<YlfFormItem icon="i-ri-question-line" label="帮助" to="/help" />
|
||||||
|
|||||||
1944
pnpm-lock.yaml
generated
1944
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user