feat: refactor more ui with app
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
65
app/components/TheAboutList.vue
Normal file
65
app/components/TheAboutList.vue
Normal 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>
|
||||
1
app/composables/global.ts
Normal file
1
app/composables/global.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const recipePanelRef = ref()
|
||||
@@ -4,6 +4,8 @@ import { isClient, useElementBounding } from '@vueuse/core'
|
||||
/**
|
||||
* trigger show invisible element
|
||||
* @param target
|
||||
*
|
||||
* @deprecated use scrollIntoView instead
|
||||
*/
|
||||
export function useInvisibleElement(target: MaybeComputedElementRef<HTMLElement>) {
|
||||
const { top } = useElementBounding(target)
|
||||
|
||||
@@ -4,4 +4,6 @@ export const appDescription = '好的,今天我们来做菜!'
|
||||
export const namespace = 'cook'
|
||||
export const lastDbUpdated = '2023-11-11 19:51:02'
|
||||
|
||||
export const icp = '苏ICP备17038157号'
|
||||
|
||||
export * from './links'
|
||||
|
||||
@@ -7,6 +7,8 @@ export const links = {
|
||||
* 兔小巢反馈
|
||||
*/
|
||||
feedback: 'https://support.qq.com/product/507827',
|
||||
githubIssue: 'https://github.com/YunYouJun/cook/issues',
|
||||
githubDiscussions: 'https://github.com/YunYouJun/cook/discussions',
|
||||
|
||||
/**
|
||||
* changelog
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
foodA,foodB,reason
|
||||
番茄,黄瓜,黄瓜中含有维生素C分解酶,会破坏番茄中的维生素C,营养流失严重
|
||||
牛奶,韭菜,牛奶与韭菜同食会影响钙的吸收,降低营养价值
|
||||
土豆,番茄,土豆会产生大量的盐酸,番茄在较强的酸性环境中会产生不溶于水的沉淀
|
||||
白萝卜,胡萝卜,白萝卜中的维生素C会被胡萝卜中的抗坏血酸酵素破坏
|
||||
芹菜,黄瓜,芹菜中的维生素C会被黄瓜中的维生素C分解酶破坏
|
||||
番茄,黄瓜,黄瓜中含有维生素C分解酶,会破坏番茄中的维生素C,营养流失严重。
|
||||
牛奶,韭菜,牛奶与韭菜同食会影响钙的吸收,降低营养价值。
|
||||
土豆,番茄,土豆会产生大量的盐酸,番茄在较强的酸性环境中会产生不溶于水的沉淀。
|
||||
白萝卜,胡萝卜,白萝卜中的维生素C会被胡萝卜中的抗坏血酸酵素破坏。
|
||||
芹菜,黄瓜,芹菜中的维生素C会被黄瓜中的维生素C分解酶破坏。
|
||||
|
||||
|
@@ -1,5 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
关于
|
||||
</div>
|
||||
<ion-page>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button default-href="/my" />
|
||||
</ion-buttons>
|
||||
<ion-title>关于</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<TheAboutList />
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
// help
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="w-full">
|
||||
<CommonHeader>
|
||||
帮助
|
||||
</CommonHeader>
|
||||
<ion-page>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button default-href="/my" />
|
||||
</ion-buttons>
|
||||
<ion-title>帮助</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<InstallPwa />
|
||||
|
||||
<FeedbackActions />
|
||||
|
||||
<div class="mx-auto p-2 rounded-2xl max-w-md w-full" text-left>
|
||||
<ion-content class="w-full">
|
||||
<div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left>
|
||||
<FAQItem title="未来计划?">
|
||||
计划增加新功能,如自定义菜谱,与使用其他用户分享的菜谱。
|
||||
</FAQItem>
|
||||
@@ -96,7 +101,7 @@
|
||||
小玩具们
|
||||
</a>。
|
||||
|
||||
<a py-4 inline-flex href="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg" target="_blank">
|
||||
<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>
|
||||
@@ -108,7 +113,7 @@
|
||||
感谢以下小伙伴为本项目提供的数据支持和 QA !
|
||||
</p>
|
||||
|
||||
<ul text-sm mt-2 text-left>
|
||||
<ul mt-2 text-left text-sm>
|
||||
<li>
|
||||
<a href="https://weibo.com/runny" target="_blank">Runny</a>
|
||||
</li>
|
||||
@@ -135,7 +140,7 @@
|
||||
</div>
|
||||
</FAQItem>
|
||||
</div>
|
||||
</div>
|
||||
<BaseFooter mt-4 />
|
||||
</div>
|
||||
<BaseFooter mt-4 />
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
@@ -7,6 +7,8 @@ useHead({
|
||||
title: '食用手册',
|
||||
})
|
||||
|
||||
const ionContentRef = ref<HTMLElement>()
|
||||
|
||||
const rStore = useRecipeStore()
|
||||
</script>
|
||||
|
||||
@@ -30,7 +32,7 @@ const rStore = useRecipeStore()
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="text-center">
|
||||
<ion-content ref="ionContentRef" class="text-center">
|
||||
<ChooseFood />
|
||||
<SimpleCopyright />
|
||||
</ion-content>
|
||||
|
||||
@@ -8,44 +8,72 @@ definePageMeta({
|
||||
|
||||
<template>
|
||||
<ion-page>
|
||||
<CommonHeader>
|
||||
我的
|
||||
</CommonHeader>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>我的</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<div
|
||||
class="mx-auto max-w-md w-full"
|
||||
px-2
|
||||
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>
|
||||
<ion-content>
|
||||
<!-- TODO -->
|
||||
<!-- <ion-list :inset="true">
|
||||
<ion-item router-link="/recipes/history">
|
||||
<ion-icon slot="start" :icon="ioniconsTimeOutline" />
|
||||
<ion-label>历史记录</ion-label>
|
||||
</ion-item>
|
||||
<ion-item router-link="/recipes/collect">
|
||||
<ion-icon slot="start" :icon="ioniconsStarOutline" />
|
||||
<ion-label>我的收藏</ion-label>
|
||||
</ion-item>
|
||||
<ion-item router-link="/cookbooks">
|
||||
<ion-icon slot="start" :icon="ioniconsBookOutline" />
|
||||
<ion-label>自定义菜谱</ion-label>
|
||||
</ion-item>
|
||||
</ion-list> -->
|
||||
|
||||
<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>
|
||||
<ion-list :inset="true">
|
||||
<ion-item :href="links.githubIssue" target="_blank">
|
||||
<ion-icon slot="start" :icon="ioniconsChatbubbleEllipsesOutline" />
|
||||
<ion-label>问题反馈</ion-label>
|
||||
</ion-item>
|
||||
<ion-item :href="links.githubDiscussions" target="_blank">
|
||||
<ion-icon slot="start" :icon="ioniconsChatbubblesOutline" />
|
||||
<ion-label>参与讨论</ion-label>
|
||||
</ion-item>
|
||||
<ion-item :href="links.contribute" target="_blank">
|
||||
<ion-icon slot="start" :icon="ioniconsMailOutline" />
|
||||
<ion-label>菜谱投稿</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<YlfForm>
|
||||
<YlfFormItem icon="i-ri-file-history-line" label="更新日志" :to="links.changelog" target="_blank" />
|
||||
</YlfForm>
|
||||
<ion-list :inset="true">
|
||||
<ion-item :href="links.changelog" target="_blank">
|
||||
<ion-icon slot="start" :icon="ioniconsDocumentTextOutline" />
|
||||
<ion-label>更新日志</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<YlfForm>
|
||||
<YlfFormItem icon="i-ri-settings-line" label="设置" to="/settings" />
|
||||
</YlfForm>
|
||||
<ion-list :inset="true">
|
||||
<ion-item router-link="/settings">
|
||||
<ion-icon slot="start" :icon="ioniconsSettingsOutline" />
|
||||
<ion-label>设置</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list :inset="true">
|
||||
<ion-item router-link="/help">
|
||||
<ion-icon slot="start" :icon="ioniconsHelpCircleOutline" />
|
||||
<ion-label>帮助</ion-label>
|
||||
</ion-item>
|
||||
<ion-item router-link="/about">
|
||||
<ion-icon slot="start" :icon="ioniconsInformationCircleOutline" />
|
||||
<ion-label>关于</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<!-- <YlfForm>
|
||||
<YlfFormItem icon="i-ri-article-line" label="自定义菜谱 TODO" to="/cookbooks/" />
|
||||
</YlfForm> -->
|
||||
|
||||
<YlfForm>
|
||||
<YlfFormItem icon="i-ri-question-line" label="帮助" to="/help" />
|
||||
<YlfFormItem icon="i-ri-information-line" label="关于" to="/help" />
|
||||
</YlfForm>
|
||||
</div>
|
||||
|
||||
<BaseFooter mt-4 />
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
@@ -17,8 +17,10 @@ useHead({
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content flex flex-grow flex-col items-center justify-center>
|
||||
<RandomRecipe />
|
||||
<ion-content>
|
||||
<div class="flex flex-grow flex-col items-center justify-center">
|
||||
<RandomRecipe />
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
@@ -117,7 +117,7 @@ export default defineNuxtConfig({
|
||||
css: {
|
||||
core: true,
|
||||
basic: true,
|
||||
utilities: true,
|
||||
// utilities: true,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user