feat: add history
This commit is contained in:
@@ -61,14 +61,14 @@ const filteredRecipes = computedAsync(async () => {
|
||||
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"
|
||||
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="mt-4 rounded-2xl"
|
||||
overflow="auto"
|
||||
flex="~ col"
|
||||
>
|
||||
<DialogTitle
|
||||
as="h3"
|
||||
class="flex items-center justify-center text-lg font-medium leading-6 text-gray-900"
|
||||
class="flex items-center justify-center text-lg font-medium leading-6"
|
||||
>
|
||||
<div relative inline-flex flex="grow">
|
||||
<div
|
||||
@@ -78,9 +78,10 @@ const filteredRecipes = computedAsync(async () => {
|
||||
<input
|
||||
v-model="keyword"
|
||||
type="text"
|
||||
class="w-full border border-gray-300 rounded-full text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 placeholder-gray-400"
|
||||
py-2 pl-10 pr-3
|
||||
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
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { DbRecipeItem } from '~/utils/db'
|
||||
import { tools } from '~/data/food'
|
||||
import type { RecipeItem } from '~/types'
|
||||
import { getEmojisFromStuff } from '~/utils'
|
||||
import { recipeHistories } from '~/composables/store/history'
|
||||
|
||||
const props = defineProps<{
|
||||
dish: RecipeItem | DbRecipeItem
|
||||
@@ -10,16 +11,21 @@ const props = defineProps<{
|
||||
|
||||
const gtm = useGtm()
|
||||
|
||||
function triggerGtm(val: string) {
|
||||
function triggerGtm(dish: RecipeItem) {
|
||||
recipeHistories.value.push({
|
||||
recipe: dish,
|
||||
time: Date.now(),
|
||||
})
|
||||
|
||||
gtm?.trackEvent({
|
||||
event: 'click',
|
||||
category: `dish_${val}`,
|
||||
category: `dish_${dish.name}`,
|
||||
action: 'click_recipe',
|
||||
label: '跳转菜谱',
|
||||
})
|
||||
gtm?.trackEvent({
|
||||
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"
|
||||
border="~ blue-200 dark:blue-800"
|
||||
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">
|
||||
{{ dishLabel }}
|
||||
|
||||
@@ -16,11 +16,11 @@ defineProps<{
|
||||
:is="to ? NuxtLink : 'div'"
|
||||
:to="to"
|
||||
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
|
||||
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 />
|
||||
<span>{{ label }}</span>
|
||||
</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`, [])
|
||||
@@ -10,7 +10,7 @@ const route = useRoute()
|
||||
<main class="text-center text-gray-700 dark:text-gray-200" p="t-5 b-15">
|
||||
<div flex items-center justify-between>
|
||||
<BackBtn ml-3 />
|
||||
<h2 flex items-center justify-center text-lg>
|
||||
<h2 flex items-center justify-center text-lg font="bold">
|
||||
{{ route.meta.title }}
|
||||
</h2>
|
||||
<DarkToggle mr-3 />
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"typecheck": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.10",
|
||||
"vue-about-me": "^1.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
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>
|
||||
@@ -8,6 +8,12 @@ import { links } from '~/constants'
|
||||
我的
|
||||
</CommonHeader>
|
||||
|
||||
<div mt-4 gap="3" grid="~ cols-3" px-2>
|
||||
<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>
|
||||
|
||||
<div
|
||||
class="mx-auto max-w-md w-full"
|
||||
px-2
|
||||
@@ -22,9 +28,9 @@ import { links } from '~/constants'
|
||||
<YlfFormItem icon="i-ri-settings-line" label="设置" to="/settings" />
|
||||
</YlfForm>
|
||||
|
||||
<YlfForm>
|
||||
<!-- <YlfForm>
|
||||
<YlfFormItem icon="i-ri-article-line" label="自定义菜谱 TODO" to="/cookbooks/" />
|
||||
</YlfForm>
|
||||
</YlfForm> -->
|
||||
|
||||
<YlfForm>
|
||||
<YlfFormItem icon="i-ri-question-line" label="帮助" to="/help" />
|
||||
|
||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -5,6 +5,9 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
dayjs:
|
||||
specifier: ^1.11.10
|
||||
version: 1.11.10
|
||||
vue-about-me:
|
||||
specifier: ^1.2.7
|
||||
version: 1.2.7(typescript@5.2.2)
|
||||
@@ -2520,6 +2523,7 @@ packages:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
micromatch: 4.0.5
|
||||
napi-wasm: 1.1.0
|
||||
dev: true
|
||||
bundledDependencies:
|
||||
- napi-wasm
|
||||
@@ -4923,6 +4927,10 @@ packages:
|
||||
whatwg-url: 12.0.1
|
||||
dev: true
|
||||
|
||||
/dayjs@1.11.10:
|
||||
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||
dev: false
|
||||
|
||||
/de-indent@1.0.2:
|
||||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||
dev: true
|
||||
@@ -7561,6 +7569,10 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/napi-wasm@1.1.0:
|
||||
resolution: {integrity: sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==}
|
||||
dev: true
|
||||
|
||||
/natural-compare-lite@1.4.0:
|
||||
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
||||
dev: true
|
||||
|
||||
Reference in New Issue
Block a user