fix some bugs 7

This commit is contained in:
2026-07-22 12:20:39 +03:30
parent 0106c94d24
commit 9319906737
4 changed files with 259 additions and 19 deletions
+196 -2
View File
@@ -1,11 +1,205 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import { getConfigApp } from '@/utils/config'
const router = useRouter()
const brandName = computed(
() => String(getConfigApp('name_fa') || getConfigApp('name') || 'خانه')
)
const logo = computed(() => String(getConfigApp('avatar') || ''))
function goHome() {
router.push({ name: 'home' })
}
function goBack() {
if (window.history.length > 1) {
router.back()
return
}
goHome()
}
</script>
<template>
<div class="text-center">صفحه مورد نظر یافت نشد</div>
<div class="not-found" dir="rtl">
<div class="not-found__glow not-found__glow--a" aria-hidden="true" />
<div class="not-found__glow not-found__glow--b" aria-hidden="true" />
<div class="not-found__grid" aria-hidden="true" />
<div class="not-found__panel">
<div v-if="logo" class="not-found__brand">
<img :src="logo" :alt="brandName" class="not-found__logo">
<span class="not-found__brand-name">{{ brandName }}</span>
</div>
<p v-else class="not-found__brand-name not-found__brand-name--solo">
{{ brandName }}
</p>
<p class="not-found__code" aria-hidden="true">۴۰۴</p>
<h1 class="not-found__title">
صفحه مورد نظر یافت نشد
</h1>
<p class="not-found__subtitle">
این مسیر وجود ندارد یا جابه‌جا شده است. می‌توانید به صفحه اصلی برگردید
و از آنجا ادامه دهید.
</p>
<div class="not-found__actions">
<a-button type="primary" size="large" class="not-found__cta" @click="goHome">
بازگشت به صفحه اصلی
</a-button>
<a-button size="large" class="not-found__secondary" @click="goBack">
صفحه قبل
</a-button>
</div>
</div>
</div>
</template>
<style scoped>
.not-found {
@apply relative min-h-screen w-full overflow-hidden flex items-center justify-center px-4 py-10;
background:
radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--App-primary, #7f1d1d) 18%, transparent), transparent 55%),
linear-gradient(165deg, #f7f4f0 0%, #efe8e0 45%, #f8f6f3 100%);
color: #1c1917;
}
</style>
.not-found__glow {
@apply pointer-events-none absolute rounded-full;
filter: blur(48px);
opacity: 0.45;
animation: not-found-float 9s ease-in-out infinite;
}
.not-found__glow--a {
width: min(48vw, 22rem);
height: min(48vw, 22rem);
top: 8%;
left: 6%;
background: color-mix(in srgb, var(--App-primary, #7f1d1d) 35%, #c4a574);
}
.not-found__glow--b {
width: min(42vw, 18rem);
height: min(42vw, 18rem);
right: 4%;
bottom: 12%;
background: color-mix(in srgb, var(--App-primary, #7f1d1d) 22%, #d6c3a3);
animation-delay: -3.5s;
}
.not-found__grid {
@apply pointer-events-none absolute inset-0 opacity-40;
background-image:
linear-gradient(rgba(28, 25, 23, 0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(28, 25, 23, 0.04) 1px, transparent 1px);
background-size: 48px 48px;
mask-image: radial-gradient(ellipse at center, black 20%, transparent 75%);
}
.not-found__panel {
@apply relative z-1 w-full max-w-lg flex flex-col items-center text-center;
animation: not-found-rise 0.7s ease-out both;
}
.not-found__brand {
@apply flex items-center justify-center gap-2.5 mb-6;
}
.not-found__logo {
@apply w-11 h-11 rounded-full object-cover;
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 8px 24px rgba(28, 25, 23, 0.12);
}
.not-found__brand-name {
@apply text-base font-bold tracking-wide text-primary m-0;
}
.not-found__brand-name--solo {
@apply mb-6;
}
.not-found__code {
@apply m-0 font-black leading-none select-none;
font-size: clamp(5.5rem, 22vw, 9rem);
letter-spacing: -0.06em;
background: linear-gradient(
135deg,
var(--App-primary, #7f1d1d) 0%,
#b45309 48%,
var(--App-primary, #7f1d1d) 100%
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 12px 28px rgba(127, 29, 29, 0.18));
animation: not-found-pulse 5.5s ease-in-out infinite;
}
.not-found__title {
@apply m-0 mt-2 text-xl md:text-2xl font-bold text-stone-900;
}
.not-found__subtitle {
@apply m-0 mt-3 text-sm md:text-base leading-7 text-stone-500 max-w-md;
}
.not-found__actions {
@apply mt-8 flex flex-wrap items-center justify-center gap-3 w-full;
}
.not-found__cta {
@apply min-w-44 font-bold;
box-shadow: 0 10px 28px color-mix(in srgb, var(--App-primary, #7f1d1d) 28%, transparent);
}
.not-found__secondary {
@apply min-w-28;
}
@keyframes not-found-rise {
from {
opacity: 0;
transform: translateY(18px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes not-found-float {
0%,
100% {
transform: translate3d(0, 0, 0) scale(1);
}
50% {
transform: translate3d(12px, -16px, 0) scale(1.05);
}
}
@keyframes not-found-pulse {
0%,
100% {
transform: translateY(0);
filter: drop-shadow(0 12px 28px rgba(127, 29, 29, 0.18));
}
50% {
transform: translateY(-6px);
filter: drop-shadow(0 18px 36px rgba(127, 29, 29, 0.26));
}
}
@media (prefers-reduced-motion: reduce) {
.not-found__glow,
.not-found__code,
.not-found__panel {
animation: none;
}
}
</style>
@@ -21,14 +21,14 @@
</div>
<div class="mt-2 flex justify-between items-center gap-2">
<div class="shrink-0">تعداد درخواستی:</div>
<div class="flex items-center gap-1 pr-cart-row__input">
<div class="flex items-center gap-1 pr-cart-row__input" @focusin="selectCountInput">
<BasicInput
v-model:value="item.count"
:addon-before="item.product.unit"
addon-bg-color="#a72b77"
addon-text-color="white"
type="text"
inputmode="numeric"
type="number"
inputmode="decimal"
/>
</div>
</div>
@@ -58,6 +58,13 @@ const displayImage = computed(() =>
}),
)
function selectCountInput(e: FocusEvent) {
const el = e.target as HTMLInputElement | null
if (!el || el.tagName !== 'INPUT' || typeof el.select !== 'function') return
// تا کاربر با تایپ عدد جدید، مقدار قبلی را جایگزین کند
requestAnimationFrame(() => el.select())
}
const emit = defineEmits<{
remove: [id: number]
}>()
@@ -1,10 +1,12 @@
<template>
<MobileRequestListView v-show="!isDesktop" />
<DesktopPhysicalReceiveListView
v-show="isDesktop"
:request-items="requestItems"
@add="openAdd"
/>
<div class="physical-receive-list-root">
<MobileRequestListView v-show="!isDesktop" />
<DesktopPhysicalReceiveListView
v-show="isDesktop"
:request-items="requestItems"
@add="openAdd"
/>
</div>
</template>
<script setup lang="ts">
@@ -16,3 +18,20 @@ import MobileRequestListView from '../mobile/MobileRequestListView.vue'
const { isDesktop } = usePhysicalReceiveShellContext()
const { requestItems, openAdd } = usePhysicalReceiveList()
</script>
<style scoped>
.physical-receive-list-root {
flex: 1 1 0;
min-height: 0;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.physical-receive-list-root > * {
flex: 1 1 0;
min-height: 0;
height: 100%;
}
</style>
@@ -1,14 +1,16 @@
<template>
<div>
<div
class="flex flex-col gap-4 mpage-content px-2 pb-[calc(var(--app-bottom-chrome-height)+var(--app-add-card-height)+1rem)]"
>
<RequestItem v-for="item in requestItems" :key="item.id" :item="item" />
<div class="physical-receive-list">
<div class="physical-receive-list__scroll mpage-content px-2">
<div
v-if="requestItems.length === 0"
class="flex flex-col items-center justify-center min-h-[40vh] text-gray-500"
class="flex flex-col gap-4 pb-[calc(var(--app-add-card-height,88px)+1.25rem)]"
>
هنوز درخواستی ثبت نشده است.
<RequestItem v-for="item in requestItems" :key="item.id" :item="item" />
<div
v-if="requestItems.length === 0"
class="flex flex-col items-center justify-center min-h-[40vh] text-gray-500"
>
هنوز درخواستی ثبت نشده است.
</div>
</div>
</div>
<Teleport v-if="!isDesktop" to="body">
@@ -29,3 +31,21 @@ import { usePhysicalReceiveShellContext } from '../composables/usePhysicalReceiv
const { requestItems, openAdd } = usePhysicalReceiveListContext()
const { isDesktop } = usePhysicalReceiveShellContext()
</script>
<style scoped>
.physical-receive-list {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
}
.physical-receive-list__scroll {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
}
</style>