1
0
mirror of synced 2025-11-06 04:20:50 +08:00

feat: refactor more ui with app

This commit is contained in:
YunYouJun
2025-10-06 18:43:58 +08:00
parent 30a92d0eb2
commit cf58e820c9
16 changed files with 255 additions and 101 deletions

View File

@@ -1,35 +1,50 @@
<script lang="ts" setup>
import { storeToRefs } from 'pinia'
const props = defineProps({
isVisible: Boolean,
})
const rStore = useRecipeStore()
const { displayedRecipe } = storeToRefs(rStore)
/**
* Show basket button if there are recipes in the basket
* scroll into view
*/
const showBasketBtn = computed(() => {
return displayedRecipe.value.length !== rStore.recipesLength && props.isVisible
})
function recipePanelScrollIntoView() {
const panel = recipePanelRef.value as HTMLElement
if (panel) {
panel.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}
</script>
<template>
<button
v-show="showBasketBtn"
class="rounded rounded-full inline-flex cursor-pointer shadow items-center justify-center fixed z-9 hover:shadow-md"
bg="green-50 dark:green-900" w="10" h="10"
bottom="22"
right="4"
text="green-600 dark:green-300"
>
<span v-if="displayedRecipe.length > 0">
<div i-mdi-bowl-mix-outline />
</span>
<span v-else>
<div i-mdi-bowl-outline />
</span>
</button>
<ion-fab slot="fixed" horizontal="end" vertical="bottom">
<!-- <button
v-show="showBasketBtn"
class="rounded rounded-full inline-flex cursor-pointer shadow items-center justify-center fixed z-9 hover:shadow-md"
bg="green-50 dark:green-900" w="10" h="10"
bottom="22"
right="4"
text="green-600 dark:green-300"
>
</button> -->
<ion-fab-button size="small">
<!-- <ion-icon :icon="add" /> -->
<span v-if="displayedRecipe.length > 0">
<div i-mdi-bowl-mix-outline />
</span>
<span v-else>
<div i-mdi-bowl-outline />
</span>
</ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button @click="rStore.reset">
<ion-icon :icon="ioniconsTrashOutline" />
</ion-fab-button>
<ion-fab-button @click="recipePanelScrollIntoView">
<ion-icon :icon="ioniconsListOutline" />
</ion-fab-button>
</ion-fab-list>
</ion-fab>
</template>

View File

@@ -19,7 +19,6 @@ const { playAnimation } = useEmojiAnimation(recipeBtnRef)
const { proxy } = useScriptGoogleTagManager()
const recipePanelRef = ref()
const { isVisible, show } = useInvisibleElement(recipePanelRef)
// 监听食材变化,自动检测相克
watch(curStuff, (newIngredients) => {
@@ -59,7 +58,14 @@ function toggleStuff(item: StuffItem, category = '', _e?: Event) {
</h2>
<!-- 食物相克警告提示 -->
<Transition name="incompatible-warning">
<ion-toast
class="incompatible-warning-toast"
:message="warningMessage"
:is-open="hasWarning"
position="top"
:icon="ioniconsWarningOutline"
animated
>
<div
v-if="hasWarning"
class="incompatible-warning-box"
@@ -84,7 +90,7 @@ function toggleStuff(item: StuffItem, category = '', _e?: Event) {
</div>
</div>
</div>
</Transition>
</ion-toast>
<div>
<h2 opacity="90" text="base" font="bold" p="1">
@@ -155,9 +161,20 @@ function toggleStuff(item: StuffItem, category = '', _e?: Event) {
</div>
</div>
<Transition>
<BasketButton ref="recipeBtnRef" :is-visible="isVisible" @click="show" />
</Transition>
<RecipePanel ref="recipePanelRef" />
</div>
<Transition>
<BasketButton ref="recipeBtnRef" />
</Transition>
</template>
<style>
ion-toast.incompatible-warning-toast {
/* --background: #f4f4fa; */
--box-shadow: 3px 3px 10px 0 rgba(0, 0, 0, 0.2);
/* --color: #4b4a50; */
--background: rgba(254, 202, 202, 0.95);
--color: #7f1d1d;
}
</style>

View File

@@ -5,24 +5,24 @@ const { random, randomRecipes } = useRandomRecipe(count)
<template>
<div inline-flex m="y-3">
<button btn p-2 rounded-full @click="dec()">
<div i-carbon-subtract />
</button>
<div font="mono" w="15" m-auto inline-block>
<ion-button shape="round" @click="dec()">
<ion-icon slot="icon-only" :icon="ioniconsRemoveOutline" />
</ion-button>
<div font="mono" class="w-15 text-center text-2xl" m-auto>
{{ count }}
</div>
<button btn p-2 rounded-full @click="inc()">
<div i-carbon-add />
</button>
<ion-button shape="round" @click="inc()">
<ion-icon slot="icon-only" :icon="ioniconsAddOutline" />
</ion-button>
</div>
<button cursor-pointer class="text-sm text-white leading-6 font-semibold px-3 py-1.5 rounded-md border-none bg-blue-600 inline-flex inline-flex shadow-sm items-center justify-center focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 focus-visible:outline hover:bg-blue-500" @click="random">
<ion-button @click="random">
<div class="transition" hover="text-blue-500" i-ri-refresh-line mr-1 inline-flex />
<div>随机一下</div>
</button>
</ion-button>
<div v-show="randomRecipes.length > 0">
<div m="t-8" flex="~ col">
<div m="t-4" flex="~ col">
<template v-for="recipe, i in randomRecipes" :key="i">
<DishTag v-if="recipe" :dish="recipe" />
</template>

View File

@@ -1,5 +1,6 @@
<script lang="ts" setup>
import { storeToRefs } from 'pinia'
import { recipePanelRef } from '~/composables/global'
const rStore = useRecipeStore()
@@ -12,15 +13,16 @@ const showTooltip = computed(() => !selectedStuff.value.length && !curTool.value
<template>
<div
class="recipe-panel shadow transition relative hover:shadow-md"
m="x-2 y-4" p="2"
ref="recipePanelRef"
class="recipe-panel relative shadow transition hover:shadow-md" m="x-2 y-4"
p="2"
bg="gray-400/8"
>
<RecipePanelTitle />
<ToggleMode />
<button right-4 top-4 absolute @click="showSearchInput = !showSearchInput">
<button absolute right-4 top-4 @click="showSearchInput = !showSearchInput">
<div v-if="!showSearchInput" i-ri-search-line />
<div v-else i-ri-search-fill />
</button>
@@ -36,7 +38,7 @@ const showTooltip = computed(() => !selectedStuff.value.length && !curTool.value
<div
v-else-if="rStore.isSearching"
text-xl p-6 flex items-center justify-center relative
relative flex items-center justify-center p-6 text-xl
>
<div class="magnifying-glass" i-ri-search-line inline-flex />
</div>

View File

@@ -0,0 +1,65 @@
<script lang="ts" setup>
import { isClient } from '@vueuse/core'
import pkg from '~/../package.json'
import { icp } from '../constants'
const displayICP = ref(true)
const commitSha = (import.meta.env.VITE_COMMIT_REF || '').slice(0, 7)
const date = import.meta.env.VITE_APP_BUILD_DATE
const buildDate = (new Date(date)).toLocaleDateString()
onBeforeMount(() => {
if (isClient)
displayICP.value = ['cook.yunyoujun.cn', 'localhost', '127.0.0.1'].includes(window.location.hostname)
})
</script>
<template>
<ion-list :inset="true">
<ion-item>
<ion-label>当前版本</ion-label>
<ion-text>v{{ pkg.version }}</ion-text>
</ion-item>
<ion-item>
<ion-label>构建时间</ion-label>
<ion-text>{{ buildDate }}</ion-text>
</ion-item>
<ion-item v-if="commitSha" :href="`https://github.com/YunYouJun/cook/commit/${commitSha}`" target="_blank">
<ion-label>Commit Hash</ion-label>
<ion-text>{{ commitSha }}</ion-text>
</ion-item>
<ion-item v-if="displayICP" href="https://beian.miit.gov.cn/" target="_blank">
<ion-label>备案号</ion-label>
<ion-text>{{ icp }}</ion-text>
</ion-item>
</ion-list>
<ion-list :inset="true">
<ion-item href="https://www.bilibili.com/blackboard/dynamic/306882" target="_blank">
<ion-label>数据来源</ion-label>
<ion-text class="inline-flex items-center justify-center">
<div class="inline-flex" i-ri-bilibili-line />
<span m="l-1" class="inline-flex">哔哩哔哩</span>
</ion-text>
</ion-item>
<ion-item href="https://github.com/YunYouJun/cook" target="_blank">
<ion-label>开源代码</ion-label>
<ion-text class="inline-flex items-center justify-center">
<div class="inline-flex" i-ri-github-line />
<span m="l-1" class="inline-flex">GitHub</span>
</ion-text>
</ion-item>
<ion-item href="https://www.yunyoujun.cn" target="_blank">
<ion-label>项目作者</ion-label>
<ion-text class="inline-flex items-center justify-center">
云游君
</ion-text>
</ion-item>
</ion-list>
</template>