1405/04/09-fix bug iphone show

This commit is contained in:
2026-06-30 18:08:00 +03:30
parent 15c43a8ee9
commit cbfca01da6
33 changed files with 664 additions and 254 deletions
+2
View File
@@ -257,7 +257,9 @@ watch(showSplash, (visible) => {
/* ارتفاع نوار اعتبار + safe-area؛ منوی پایین با bottom: var(--app-credit-footer-offset) بالاتر از این نوار می‌نشیند */
:root {
--app-credit-bar-inner: 28px;
--app-safe-top: env(safe-area-inset-top, 0px);
--app-safe-bottom: env(safe-area-inset-bottom, 0px);
--app-home-header-offset: calc(4.25rem + var(--app-safe-top));
--app-credit-footer-offset: calc(var(--app-credit-bar-inner) + var(--app-safe-bottom));
--app-nav-height: 80px;
--app-bottom-chrome-height: calc(var(--app-nav-height) + var(--app-credit-footer-offset));
+120 -5
View File
@@ -1,10 +1,35 @@
/* Shared mobile page chrome */
/* Shared mobile page chrome (inner pages — not home .app-header) */
:root {
--mpage-header-bar: 2.75rem;
--mpage-header-offset: calc(4rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
--mpage-subheader-offset: calc(var(--mpage-header-bar) + var(--app-safe-top, env(safe-area-inset-top, 0px)));
--mpage-content-with-subheader: calc(6.5rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
--mpage-scroll-max-height: calc(100dvh - 50px - var(--app-safe-top, env(safe-area-inset-top, 0px)));
--mobile-info-support-block: calc(5rem + var(--app-safe-bottom, env(safe-area-inset-bottom, 0px)));
}
/* Fixed top bar: background fills under status bar; content sits below safe area */
.mobile-top-chrome {
top: 0;
box-sizing: border-box;
padding-top: calc(0.75rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
}
.mobile-top-chrome.h-12,
.mobile-top-chrome.min-h-12 {
height: auto;
min-height: calc(3rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
}
.mpage-header {
display: flex;
align-items: center;
gap: 0.5rem;
top: 0;
box-sizing: border-box;
padding: 0.75rem;
padding-top: calc(0.75rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
background: #fff;
color: @App-primary-color;
font-size: 1rem;
@@ -38,7 +63,7 @@
}
.mpage-subheader {
top: 2.75rem;
top: var(--mpage-subheader-offset);
z-index: 1999;
padding: 0.75rem;
background: #fff;
@@ -47,14 +72,104 @@
}
.mpage-content {
padding-top: 4rem;
padding-top: var(--mpage-header-offset);
}
.mpage-content--with-subheader {
padding-top: 6.5rem;
padding-top: var(--mpage-content-with-subheader);
}
.mpage-scroll {
overflow-y: auto;
max-height: calc(100vh - 50px);
max-height: var(--mpage-scroll-max-height);
}
.mobile-page-body--pt10 {
padding-top: calc(2.5rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
}
.mobile-page-body--pt15 {
padding-top: calc(3.75rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
}
.mobile-page-body--pt20 {
padding-top: calc(5rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
}
/* Info pages (about, educate): fixed shell, scroll inside content box only */
.mobile-info-page {
position: relative;
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
max-height: 100%;
overflow: hidden;
}
.mobile-info-page__bg {
pointer-events: none;
position: absolute;
inset: 0;
overflow: hidden;
z-index: 0;
img {
position: absolute;
bottom: 0;
width: 100%;
}
}
.mobile-info-page__main {
position: relative;
z-index: 1;
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
padding-top: calc(var(--mpage-header-offset) + 1rem);
padding-right: 2.5rem;
padding-left: 2.5rem;
padding-bottom: calc(
var(--mobile-info-support-block, 5rem) + var(--app-credit-footer-offset, 28px) + 1.25rem
);
pointer-events: none;
> * {
pointer-events: auto;
}
}
.mobile-info-page__support {
bottom: var(--app-credit-footer-offset, 28px);
box-sizing: border-box;
padding: 1rem 2.5rem;
padding-bottom: calc(1rem + var(--app-safe-bottom, env(safe-area-inset-bottom, 0px)));
background: #fff;
box-shadow: 0 -2px 8px rgba(15, 23, 42, 0.06);
z-index: 1998;
}
.mobile-info-page__header {
z-index: 1999;
}
.mobile-content-box {
display: flex;
flex-direction: column;
flex: 1 1 0;
min-height: 0;
overflow: hidden;
margin-bottom: 0.75rem;
}
.mobile-content-box__scroll {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
}
@@ -1,13 +1,16 @@
<template>
<div
:class="variant === 'desktop'
? (isBoursecu ? 'dabout-content--boursecu' : 'dabout-content--default')
: (isBoursecuProject()
? 'mt-5 border-solid border-2 border-primary text-primary rounded-[12px] p-4 text-xs leading-5'
: 'bg-primary text-white rounded-[12px] p-4 text-xs leading-5')"
class="dabout-content"
:class="[
variant === 'desktop'
? (isBoursecu ? 'dabout-content--boursecu' : 'dabout-content--default')
: (isBoursecuProject()
? 'border-solid border-2 border-primary text-primary rounded-[12px] p-4 text-xs leading-5 mobile-content-box'
: 'bg-primary text-white rounded-[12px] p-4 text-xs leading-5 mobile-content-box'),
'dabout-content',
]"
>
<template v-for="(section, sectionIndex) in aboutSections" :key="sectionIndex">
<div :class="variant !== 'desktop' ? 'mobile-content-box__scroll' : undefined">
<template v-for="(section, sectionIndex) in aboutSections" :key="sectionIndex">
<div
v-if="sectionIndex > 0"
:class="variant === 'desktop' ? 'dabout-content__divider' : 'w-full h-1px my-3 bg-tertiary'"
@@ -46,6 +49,7 @@
v-if="variant !== 'desktop'"
class="w-full h-1px my-3 bg-tertiary"
></div>
</div>
</div>
</template>
@@ -1,5 +1,5 @@
<template>
<div :class="variant === 'desktop' ? 'dabout-support' : 'wrap-fix bottom-0 px-10 pb-3rem flex gap-2 bg-white'">
<div :class="variant === 'desktop' ? 'dabout-support' : 'wrap-fix mobile-info-page__support flex gap-2'">
<a
class="w-full"
:href="supportHref"
+9
View File
@@ -20,5 +20,14 @@ useAboutPage()
.about-page-root {
min-height: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
<style lang="less">
.about-page-root.main-with-bottom-chrome-inner {
overflow: hidden;
}
</style>
@@ -1,24 +1,18 @@
<template>
<div>
<div class="bg-white wrap-fix z-200001 py-3 px-3 text-primary font-bold drop-shadow flex">
<div class="mobile-info-page">
<div class="mobile-info-page__bg" aria-hidden="true">
<img :src="img" alt="" />
</div>
<div class="bg-white wrap-fix mobile-top-chrome mobile-info-page__header px-3 pb-3 text-primary font-bold drop-shadow flex">
<div class="cursor-pointer" @click="router.back()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
</div>
<div class="mr-2">درباره ما</div>
</div>
<div class="pt-20">
<div>
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
</div>
<div class="text-justify text-base z-200000 relative">
<div class="px-10">
<div class="overflow-y-auto h-65vh pb-20">
<AboutSectionsContent variant="mobile" />
</div>
</div>
<AboutSupportActions variant="mobile" />
</div>
<div class="mobile-info-page__main">
<AboutSectionsContent variant="mobile" />
</div>
<AboutSupportActions variant="mobile" />
</div>
</template>
@@ -2,41 +2,43 @@
<div
:class="variant === 'desktop'
? 'daboutus-content'
: 'mt-5 text-5 border-solid border-2 border-[#093D51] text-[#093D51] rounded-[12px] p-4'"
: 'text-5 border-solid border-2 border-[#093D51] text-[#093D51] rounded-[12px] p-4 mobile-content-box'"
>
<img
v-if="variant !== 'desktop'"
:src="config.config?.avatar"
class="mb-2 mt-5 w-10rem"
style="justify-self: center"
alt=""
/>
<div :class="variant !== 'desktop' ? 'mobile-content-box__scroll' : undefined">
<img
v-if="variant !== 'desktop'"
:src="config.config?.avatar"
class="mb-2 mt-5 w-10rem"
style="justify-self: center"
alt=""
/>
<div :class="variant === 'desktop' ? 'daboutus-content__body' : 'text-sm leading-7 space-y-2'">
<h2 :class="variant === 'desktop' ? 'daboutus-content__title' : 'text-base font-bold mb-3'">درباره ما</h2>
<div :class="variant === 'desktop' ? 'daboutus-content__body' : 'text-sm leading-7 space-y-2'">
<h2 :class="variant === 'desktop' ? 'daboutus-content__title' : 'text-base font-bold mb-3'">درباره ما</h2>
<div :class="variant === 'desktop' ? 'daboutus-content__paragraph' : 'mt-3'">
گروسی گالری بستری امن و آنلاین برای خرید و فروش طلای آبشده فراهم کرده تا کاربران بتوانند سرمایه‌های خرد خود را به راحتی پس‌انداز و مدیریت کنند.
<div :class="variant === 'desktop' ? 'daboutus-content__paragraph' : 'mt-3'">
گروسی گالری بستری امن و آنلاین برای خرید و فروش طلای آبشده فراهم کرده تا کاربران بتوانند سرمایه‌های خرد خود را به راحتی پس‌انداز و مدیریت کنند.
</div>
<div :class="variant === 'desktop' ? 'daboutus-content__paragraph' : 'mt-3'">
هدف ما ایجاد تجربه‌ای سریع، شفاف و کاربرپسند در معاملات طلای آبشده است.
</div>
</div>
<div :class="variant === 'desktop' ? 'daboutus-content__paragraph' : 'mt-3'">
هدف ما ایجاد تجربه‌ای سریع، شفاف و کاربرپسند در معاملات طلای آبشده است.
</div>
</div>
<div :class="variant === 'desktop' ? 'daboutus-content__enamad' : ''" style="justify-self: center">
<a
referrerpolicy="origin"
target="_blank"
href="https://trustseal.enamad.ir/?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
>
<img
<div :class="variant === 'desktop' ? 'daboutus-content__enamad' : ''" style="justify-self: center">
<a
referrerpolicy="origin"
src="https://trustseal.enamad.ir/logo.aspx?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
alt="enamad"
style="cursor:pointer"
code="DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
/>
</a>
target="_blank"
href="https://trustseal.enamad.ir/?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
>
<img
referrerpolicy="origin"
src="https://trustseal.enamad.ir/logo.aspx?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
alt="enamad"
style="cursor:pointer"
code="DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
/>
</a>
</div>
</div>
</div>
</template>
+3
View File
@@ -20,5 +20,8 @@ useAboutUsPage()
.about-us-page-root {
min-height: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
@@ -1,22 +1,16 @@
<template>
<div>
<div class="wrap-fix z-1 bg-white py-3 px-3 text-black font-bold drop-shadow flex">
<div class="mobile-info-page">
<div class="mobile-info-page__bg" aria-hidden="true">
<img :src="img" alt="" />
</div>
<div class="wrap-fix mobile-top-chrome mobile-info-page__header bg-white px-3 pb-3 text-black font-bold drop-shadow flex">
<div class="cursor-pointer" @click="router.back()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
</div>
<div class="mr-2">درباره ما</div>
</div>
<div class="pt-20">
<div>
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
</div>
<div class="text-justify text-base z-200000 relative">
<div class="px-10">
<div class="overflow-y-auto h-65vh pb-20 border-[#093D51]">
<AboutUsContentPanel variant="mobile" />
</div>
</div>
</div>
<div class="mobile-info-page__main">
<AboutUsContentPanel variant="mobile" />
</div>
</div>
</template>
+100 -28
View File
@@ -2,28 +2,73 @@
<a-form
ref="formRef"
:model="address"
:class="variant === 'desktop' ? 'daddr-form' : '!mt-5'"
:class="variant === 'desktop' ? 'daddr-form' : 'address-form-mobile'"
name="address-form"
>
<div :class="variant === 'desktop' ? 'daddr-form__fields' : 'flex flex-col items-center'">
<div
v-if="variant !== 'desktop'"
class="font-bold text-lg mb-2"
>
آدرس
<template v-if="variant === 'desktop'">
<div class="daddr-form__fields">
<div class="daddr-form__grid">
<a-form-item label="استان" name="province" :rules="[required()]">
<BasicSelect
v-model:value="address.province"
:items="provinceList"
value-name="title"
key-name="title"
size="large"
@change="changeProvince"
/>
</a-form-item>
<a-form-item label="شهر" name="city" :rules="[required()]">
<BasicSelect
v-model:value="address.city"
:disabled="!cityList"
value-name="title"
:items="cityList"
key-name="title"
size="large"
/>
</a-form-item>
<a-form-item label="کد پستی" name="zip" :rules="[required()]">
<BasicInput
v-model:value="address.zip"
placeholder="کد پستی را وارد نمایید"
size="large"
/>
</a-form-item>
<a-form-item label="تلفن تماس" name="phone" :rules="[required()]">
<BasicInput
v-model:value="address.phone"
placeholder="تلفن تماس را وارد نمایید"
size="large"
/>
</a-form-item>
<a-form-item
label="آدرس کامل"
name="address"
:rules="[required()]"
class="daddr-form__address-item"
>
<BasicTextArea
v-model:value="address.address"
placeholder="آدرس کامل را وارد نمایید"
/>
</a-form-item>
<BasicButton class="daddr-form__submit" type="primary" @click="handleOk">
{{ editId ? 'ویرایش آدرس' : 'ثبت آدرس' }}
</BasicButton>
</div>
</div>
<div
:class="variant === 'desktop'
? 'daddr-form__grid'
: 'flex flex-col gap-4 pb-20 w-full h-60vh overflow-y-scroll'"
>
</template>
<template v-else>
<div class="address-form-mobile__title">آدرس</div>
<div class="address-form-mobile__scroll">
<a-form-item label="استان" name="province" :rules="[required()]">
<BasicSelect
v-model:value="address.province"
:items="provinceList"
value-name="title"
key-name="title"
:size="variant === 'desktop' ? 'large' : undefined"
@change="changeProvince"
/>
</a-form-item>
@@ -34,43 +79,33 @@
value-name="title"
:items="cityList"
key-name="title"
:size="variant === 'desktop' ? 'large' : undefined"
/>
</a-form-item>
<a-form-item label="کد پستی" name="zip" :rules="[required()]">
<BasicInput
v-model:value="address.zip"
placeholder="کد پستی را وارد نمایید"
:size="variant === 'desktop' ? 'large' : undefined"
/>
</a-form-item>
<a-form-item label="تلفن تماس" name="phone" :rules="[required()]">
<BasicInput
v-model:value="address.phone"
placeholder="تلفن تماس را وارد نمایید"
:size="variant === 'desktop' ? 'large' : undefined"
/>
</a-form-item>
<a-form-item
label="آدرس کامل"
name="address"
:rules="[required()]"
:class="variant === 'desktop' ? 'daddr-form__address-item' : ''"
>
<a-form-item label="آدرس کامل" name="address" :rules="[required()]">
<BasicTextArea
v-model:value="address.address"
placeholder="آدرس کامل را وارد نمایید"
/>
</a-form-item>
<BasicButton
:class="variant === 'desktop' ? 'daddr-form__submit' : '!text-white px-3 pb-4rem'"
type="primary"
@click="handleOk"
>
</div>
<div class="address-form-mobile__footer">
<BasicButton class="w-full !text-white" type="primary" @click="handleOk">
{{ editId ? 'ویرایش آدرس' : 'ثبت آدرس' }}
</BasicButton>
</div>
</div>
</template>
</a-form>
</template>
@@ -99,3 +134,40 @@ const {
handleOk,
} = useAddressPageContext()
</script>
<style scoped>
.address-form-mobile {
display: flex;
flex-direction: column;
height: calc(80dvh - 3.5rem);
min-height: 0;
margin-top: 0.75rem;
}
.address-form-mobile__title {
flex-shrink: 0;
margin-bottom: 0.5rem;
font-size: 1.125rem;
font-weight: 700;
}
.address-form-mobile__scroll {
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
gap: 1rem;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
padding-bottom: 0.5rem;
}
.address-form-mobile__footer {
flex-shrink: 0;
padding-top: 0.75rem;
padding-bottom: calc(0.25rem + env(safe-area-inset-bottom, 0px));
background: #fff;
border-top: 1px solid #f3f4f6;
}
</style>
@@ -1,12 +1,12 @@
<template>
<div>
<div class="wrap-fix z-1 bg-white py-3 px-3 text-black font-bold drop-shadow flex">
<div class="wrap-fix mobile-top-chrome z-1 bg-white px-3 pb-3 text-black font-bold drop-shadow flex">
<div class="cursor-pointer" @click="router.back()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
</div>
<div class="mr-2">آموزش نرم افزار</div>
</div>
<div class="pt-10">
<div class="mobile-page-body--pt10">
<div class="text-justify text-base z-200000 relative">
<div class="px-10">
<div class="overflow-y-auto h-60vh pb-10 border-[#093D51]">
@@ -1,7 +1,7 @@
<template>
<div>
<div
class="bg-white wrap-fix py-3 px-3 text-primary font-bold drop-shadow flex h-12 z-20 justify-between"
class="bg-white wrap-fix mobile-top-chrome px-3 pb-3 text-primary font-bold drop-shadow flex min-h-12 z-20 justify-between"
>
<div class="flex">
<div class="cursor-pointer" @click="goBack()">
@@ -10,7 +10,7 @@
<div class="mr-2">{{ info?.title }}</div>
</div>
</div>
<div class="pt-20 flex flex-col justify-center items-center">
<div class="mobile-page-body--pt20 flex flex-col justify-center items-center">
<a-spin :spinning="loading">
<div class="bg-sky-100 w-[120px] aspect-square flex justify-center rounded-xl">
<img v-if="info?.group_type == 'گوی'" :src="goyImg" alt="" />
@@ -1,7 +1,7 @@
<template>
<div>
<div
class="bg-white w-full py-3 px-3 text-primary font-bold drop-shadow fixed md:absolute top-0 flex h-12 z-20"
class="bg-white w-full mobile-top-chrome px-3 pb-3 text-primary font-bold drop-shadow fixed md:absolute top-0 flex min-h-12 z-20"
>
<div @click="goBack()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
@@ -22,7 +22,7 @@
"
/>
<div
class="pt-15 flex flex-col relative z-10"
class="mobile-page-body--pt15 flex flex-col relative z-10"
:class="isBazretalaProject() ? 'text-white' : 'text-tertiary'"
>
<div class="font-bold mr-5 z-20">موجودی دارایی ها</div>
@@ -1,7 +1,7 @@
<template>
<div>
<div
class="bg-white wrap-fix py-3 px-3 text-primary font-bold drop-shadow flex h-12 z-20 justify-between"
class="bg-white wrap-fix mobile-top-chrome px-3 pb-3 text-primary font-bold drop-shadow flex min-h-12 z-20 justify-between"
>
<div class="flex">
<div class="cursor-pointer" @click="goBack()">
@@ -11,7 +11,7 @@
</div>
</div>
<a-spin :spinning="loading">
<div class="pt-20 flex flex-col justify-center items-center">
<div class="mobile-page-body--pt20 flex flex-col justify-center items-center">
<div class="bg-sky-100 w-[120px] aspect-square flex justify-center rounded-xl">
<img :src="itemImg" alt="" />
</div>
@@ -1,6 +1,6 @@
<template>
<div>
<MobilePageHeader title="کارت هدیه" />
<MobilePageHeader title="کارت هدیه" show-back />
<div class="px-5 mpage-content pb-2">
<div class="border-gray-200 border-1 rounded-xl p-5 trans h-40 relative">
<bg_main />
+4 -1
View File
@@ -1,7 +1,7 @@
<template>
<div
ref="headerRef"
class="app-header px-4 py-2 top-0 z-30 wrap-fix background-color-transition"
class="app-header px-4 pb-2 top-0 wrap-fix background-color-transition"
:class="{ 'app-header--scrolled': isHeaderScrolled }"
>
<div class="flex justify-between my-2 items-center">
@@ -169,6 +169,9 @@ defineEmits<{
<style scoped>
.app-header {
z-index: 1999;
box-sizing: border-box;
padding-top: calc(0.5rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
background-color: transparent;
}
+4
View File
@@ -47,6 +47,10 @@ const {
</style>
<style lang="less">
.home-page-root.main-with-bottom-chrome-inner {
scroll-padding-top: var(--app-home-header-offset, calc(4.25rem + env(safe-area-inset-top, 0px)));
}
.odometer {
font-size: 60px;
text-align: center;
@@ -1,5 +1,5 @@
<template>
<div class="mt-10 p-5 home-mobile-root">
<div class="home-mobile-root p-5">
<div class="app-header-scroll-sentinel" aria-hidden="true" />
<component :is="layoutComponent" :layout-config="layoutConfig" />
<AppHeader @logout="$emit('logout')" />
@@ -26,6 +26,7 @@ const layoutConfig = computed(() => getHomeLayoutConfig(getHomeLayoutId()))
<style scoped>
.home-mobile-root {
position: relative;
padding-top: var(--app-home-header-offset, calc(4.25rem + env(safe-area-inset-top, 0px)));
}
.app-header-scroll-sentinel {
+23 -1
View File
@@ -2,7 +2,7 @@
<div class="physical-receive-page-root" :class="{ 'physical-receive-page-root--desktop': isDesktop }">
<MobilePhysicalReceiveChrome v-show="!isDesktop" />
<div :class="isDesktop ? 'dpr' : ''">
<div :class="isDesktop ? 'dpr' : 'physical-receive-page-root__shell'">
<div :class="isDesktop ? 'dpr__container' : 'physical-receive-page-root__content'">
<DesktopPhysicalReceiveChrome v-show="isDesktop" />
<router-view />
@@ -21,16 +21,38 @@ const { isDesktop } = usePhysicalReceiveShell()
<style scoped>
.physical-receive-page-root {
display: flex;
flex-direction: column;
min-height: 100%;
height: 100%;
overflow: hidden;
}
.physical-receive-page-root__shell {
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.physical-receive-page-root__content {
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.physical-receive-page-root--desktop {
height: auto;
min-height: 0;
overflow: visible;
}
</style>
<style lang="less">
.physical-receive-page-root.main-with-bottom-chrome-inner {
overflow: hidden;
}
</style>
@@ -1,7 +1,7 @@
<template>
<div>
<div ref="el" class="px-3 mpage-content pb-2">
<div class="flex gap-2">
<div class="physical-new-request">
<div class="physical-new-request__toolbar mpage-content">
<div class="flex gap-2 px-3">
<BasicSelect
v-model:value="selectedProduct"
:items="items"
@@ -17,18 +17,24 @@
افزودن
</BasicButton>
</div>
<div class="h-70vh rounded-lg bg-white mt-2 border-gray-200 border-1 overflow-y-auto p-2">
</div>
<div class="physical-new-request__items px-3">
<div class="physical-new-request__items-scroll">
<div
v-for="val in selectedProducts"
:key="val.product.id"
class="rounded-lg p-2 bg-gray-100 mb-2"
class="rounded-lg p-2 bg-gray-100 mb-2 last:mb-0"
>
<PhysicalReceiveCartRow :item="val" @remove="handleRemove" />
</div>
</div>
</div>
<div class="physical-new-request__footer px-3">
<BasicButton
:disabled-b="selectedProducts.length == 0"
class="w-full absolute bottom-10 mt-2"
class="w-full"
@click="handelFirstSubmit()"
>
ثبت
@@ -74,3 +80,46 @@ const {
handleAddress,
} = useNewPhysicalRequestContext()
</script>
<style scoped>
.physical-new-request {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
}
.physical-new-request__toolbar {
flex-shrink: 0;
padding-bottom: 0.5rem;
}
.physical-new-request__items {
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
padding-bottom: 0.5rem;
}
.physical-new-request__items-scroll {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
background: #fff;
padding: 0.5rem;
}
.physical-new-request__footer {
flex-shrink: 0;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
background: #fff;
border-top: 1px solid #f3f4f6;
}
</style>
@@ -1,7 +1,5 @@
<template>
<div class="physical-receive-mobile-chrome" style="max-height: calc(100vh - 50px)">
<MobilePageHeader :title="pageTitle" show-back />
</div>
<MobilePageHeader :title="pageTitle" show-back />
</template>
<script lang="ts" setup>
+9
View File
@@ -106,5 +106,14 @@ const {
.products-page-root {
min-height: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
<style lang="less">
.products-page-root.main-with-bottom-chrome-inner {
overflow: hidden;
}
</style>
@@ -1,41 +1,45 @@
<template>
<div class="products-mobile-root">
<div class="bottom-0 fixed top-0">
<img :src="img" alt="" class="w-inherit" :style="{ backgroundRepeat: 'repeat' }" />
<div class="products-mobile-root__bg" aria-hidden="true">
<img :src="img" alt="" />
</div>
<MobilePageHeader title="خرید و فروش" />
<a-spin :spinning="loading">
<div class="!h-full overflow-y-scroll mpage-content mpage-scroll">
<!-- بنر بسته بودن فروشگاه -->
<div v-if="storeClosed" class="mx-4 mt-4 closed-banner">
<div class="closed-banner__icon">🔒</div>
<div class="closed-banner__body">
<div class="closed-banner__title">فروشگاه بسته است</div>
<div v-if="storeClosedMessage" class="closed-banner__hint">{{ storeClosedMessage }}</div>
</div>
<div class="products-mobile-root__chrome mpage-content">
<div v-if="storeClosed" class="mx-4 mt-4 closed-banner">
<div class="closed-banner__icon">🔒</div>
<div class="closed-banner__body">
<div class="closed-banner__title">فروشگاه بسته است</div>
<div v-if="storeClosedMessage" class="closed-banner__hint">{{ storeClosedMessage }}</div>
</div>
</div>
<div class="w-full flex justify-center top-0 py-5">
<ARadioGroup
v-model:value="activekey"
size="large"
button-style="solid"
@change="changeTab"
<div class="products-mobile-root__tabs">
<ARadioGroup
v-model:value="activekey"
size="large"
button-style="solid"
@change="changeTab"
>
<ARadioButton class="cats" value="همه">همه</ARadioButton>
<ARadioButton
v-for="item in typeItems"
:key="item"
class="cats"
:value="item"
>
<ARadioButton class="cats" value="همه">همه</ARadioButton>
<ARadioButton
v-for="item in typeItems"
:key="item"
class="cats"
:value="item"
>
{{ item }}
</ARadioButton>
</ARadioGroup>
</div>
{{ item }}
</ARadioButton>
</ARadioGroup>
</div>
</div>
<div class="mx-5 pb-30 pt-2" style="color: #1b2b07">
<div class="products-mobile-root__scroll">
<a-spin :spinning="loading">
<div
class="products-mobile-root__list mx-5 pb-[calc(var(--app-bottom-chrome-height)+1rem)] pt-2"
style="color: #1b2b07"
>
<div v-for="item in items" :key="item.id" class="mt-3">
<ProductItem
:ProductItem="item"
@@ -44,8 +48,8 @@
/>
</div>
</div>
</div>
</a-spin>
</a-spin>
</div>
</div>
</template>
@@ -71,6 +75,62 @@ const storeClosed = computed(() => getPriceDisplayState() === 'closed' || isStor
const storeClosedMessage = computed(() => getStoreClosedMessage())
</script>
<style scoped>
.products-mobile-root {
position: relative;
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
max-height: 100%;
overflow: hidden;
}
.products-mobile-root__bg {
pointer-events: none;
position: absolute;
inset: 0;
overflow: hidden;
z-index: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.products-mobile-root__chrome {
position: relative;
z-index: 1;
flex: 0 0 auto;
}
.products-mobile-root__tabs {
display: flex;
justify-content: center;
width: 100%;
padding: 1.25rem 0.75rem 0.75rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.products-mobile-root__scroll {
position: relative;
z-index: 1;
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
}
.products-mobile-root__list {
min-height: min-content;
}
</style>
<style lang="less">
.cats:hover span {
--un-text-opacity: 1;
@@ -1,31 +1,35 @@
<template>
<div
:class="variant === 'desktop' ? 'drules-content' : 'rules-panel mt-5 border-solid border-2 border-primary text-primary rounded-[12px] p-4'"
:class="variant === 'desktop'
? 'drules-content'
: 'rules-panel border-solid border-2 border-primary text-primary rounded-[12px] p-4 mobile-content-box'"
>
<div :class="variant === 'desktop' ? 'drules-content__title' : 'font-bold text-sm text-primary'">
{{ rulesTitle }}
</div>
<div
:class="variant === 'desktop' ? 'drules-content__divider' : 'w-full h-1px my-3 bg-secondary'"
></div>
<div
v-for="(block, blockIndex) in rulesBlocks"
:key="`block-${blockIndex}`"
:class="variant === 'desktop' ? 'drules-content__block' : 'rules-block'"
>
<div
v-if="block.title"
:class="variant === 'desktop' ? 'drules-content__block-title' : 'font-bold text-sm text-primary mt-4 mb-2'"
>
{{ block.title }}
<div :class="variant !== 'desktop' ? 'mobile-content-box__scroll' : undefined">
<div :class="variant === 'desktop' ? 'drules-content__title' : 'font-bold text-sm text-primary'">
{{ rulesTitle }}
</div>
<p
v-for="(rule, index) in block.items"
:key="`rule-${blockIndex}-${index}`"
:class="variant === 'desktop' ? 'drules-content__paragraph' : 'rules-paragraph'"
<div
:class="variant === 'desktop' ? 'drules-content__divider' : 'w-full h-1px my-3 bg-secondary'"
></div>
<div
v-for="(block, blockIndex) in rulesBlocks"
:key="`block-${blockIndex}`"
:class="variant === 'desktop' ? 'drules-content__block' : 'rules-block'"
>
{{ rule }}
</p>
<div
v-if="block.title"
:class="variant === 'desktop' ? 'drules-content__block-title' : 'font-bold text-sm text-primary mt-4 mb-2'"
>
{{ block.title }}
</div>
<p
v-for="(rule, index) in block.items"
:key="`rule-${blockIndex}-${index}`"
:class="variant === 'desktop' ? 'drules-content__paragraph' : 'rules-paragraph'"
>
{{ rule }}
</p>
</div>
</div>
</div>
</template>
@@ -1,5 +1,5 @@
<template>
<div :class="variant === 'desktop' ? 'drules-support' : 'wrap-fix bottom-0 px-10 pb-3rem flex gap-2 bg-white'">
<div :class="variant === 'desktop' ? 'drules-support' : 'wrap-fix mobile-info-page__support flex gap-2'">
<a
class="w-full"
:href="supportHref"
+9
View File
@@ -20,5 +20,14 @@ useRulesPage()
.rules-page-root {
min-height: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
<style lang="less">
.rules-page-root.main-with-bottom-chrome-inner {
overflow: hidden;
}
</style>
@@ -1,31 +1,19 @@
<template>
<div>
<div class="wrap-fix z-1 bg-white py-3 px-3 text-primary font-bold drop-shadow flex">
<div class="cursor-pointer" @click="router.back()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
</div>
<div class="mr-2">قوانین و مقررات</div>
<div class="mobile-info-page">
<div class="mobile-info-page__bg" aria-hidden="true">
<img :src="img" alt="" />
</div>
<div class="pt-20">
<div>
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
</div>
<div class="text-base z-200000 relative">
<div class="px-10">
<div class="overflow-y-auto h-60vh pb-20 border-primary">
<RulesContentPanel variant="mobile" />
</div>
</div>
<RulesSupportActions variant="mobile" />
</div>
<MobilePageHeader title="قوانین و مقررات" show-back />
<div class="mobile-info-page__main">
<RulesContentPanel variant="mobile" />
</div>
<RulesSupportActions variant="mobile" />
</div>
</template>
<script lang="ts" setup>
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import img from '@/assets/img/user_ly1.svg'
import router from '@/router'
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
import RulesContentPanel from '../components/RulesContentPanel.vue'
import RulesSupportActions from '../components/RulesSupportActions.vue'
</script>
@@ -29,7 +29,7 @@
<BasicActionSheet v-model:show="showFilter">
<div class="font-bold text-lg">فیلتر</div>
<div class="pb-20 mt-5">
<div class="pb-10 mt-5">
<a-form-item class="w-full gap-2 !flex-col" label="تاریخ" name="password">
<BaseDatePicker v-model:value="dateFilter" class="w-full" size="large" />
</a-form-item>
@@ -22,7 +22,7 @@
<div v-if="showSubmit" class="md:w-[395px] pt-3rem px-3">
<BasicButton
:disabled="loading"
class="w-full py-2 mb-20"
class="w-full py-2 "
html-type="submit"
type="primary"
>
@@ -1,37 +1,43 @@
<template>
<a-form ref="formRef" :model="userFormState" class="!mt-5" name="basic" @finish="ok">
<a-form-item :rules="[isValidPersian()]" label="نام" name="fname">
<BasicInput v-model:value="userFormState.fname" />
</a-form-item>
<a-form-item :rules="[isValidPersian()]" label="نام خانوادگی" name="lname">
<BasicInput v-model:value="userFormState.lname" />
</a-form-item>
<a-form-item label="تاریخ تولد" name="birth_date">
<BaseDatePicker v-model:value="userFormState.birth_date" class="w-full" inputReadOnly />
</a-form-item>
<a-form-item :rules="[requireNationalCode()]" label="شماره ملی" name="n_code">
<BasicInput
v-model:value="userFormState.n_code"
type="number"
:disabled="userFormState.is_legal == 1 || userFormState.is_legal == 2"
/>
</a-form-item>
<a-form-item label="نام شهر" name="city">
<BasicInput v-model:value="userFormState.city" />
</a-form-item>
<a-form-item v-if="showSubmit">
<div class="wrap-fix md:w-[395px] bottom-5 px-3">
<BasicButton
:disabled="loading"
class="w-full py-2 mb-20"
html-type="submit"
type="primary"
>
<a-spin v-if="loading" size="small" />
<span v-else>ثبت</span>
</BasicButton>
</div>
</a-form-item>
<a-form
ref="formRef"
:model="userFormState"
:class="showSubmit ? 'user-profile-form-mobile' : '!mt-5'"
name="basic"
@finish="ok"
>
<div :class="showSubmit ? 'user-profile-form-mobile__scroll' : undefined">
<a-form-item :rules="[isValidPersian()]" label="نام" name="fname">
<BasicInput v-model:value="userFormState.fname" />
</a-form-item>
<a-form-item :rules="[isValidPersian()]" label="نام خانوادگی" name="lname">
<BasicInput v-model:value="userFormState.lname" />
</a-form-item>
<a-form-item label="تاریخ تولد" name="birth_date">
<BaseDatePicker v-model:value="userFormState.birth_date" class="w-full" inputReadOnly />
</a-form-item>
<a-form-item :rules="[requireNationalCode()]" label="شماره ملی" name="n_code">
<BasicInput
v-model:value="userFormState.n_code"
type="number"
:disabled="userFormState.is_legal == 1 || userFormState.is_legal == 2"
/>
</a-form-item>
<a-form-item label="نام شهر" name="city">
<BasicInput v-model:value="userFormState.city" />
</a-form-item>
</div>
<div v-if="showSubmit" class="user-profile-form-mobile__footer">
<BasicButton
:disabled="loading"
class="w-full py-2"
html-type="submit"
type="primary"
>
<a-spin v-if="loading" size="small" />
<span v-else>ثبت</span>
</BasicButton>
</div>
</a-form>
</template>
@@ -57,3 +63,30 @@ const {
ok,
} = useUserPageContext()
</script>
<style scoped>
.user-profile-form-mobile {
display: flex;
flex-direction: column;
flex: 1 1 0;
min-height: 0;
height: 100%;
}
.user-profile-form-mobile__scroll {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
padding-bottom: 0.5rem;
}
.user-profile-form-mobile__footer {
flex-shrink: 0;
padding-top: 0.75rem;
padding-bottom: calc(0.25rem + env(safe-area-inset-bottom, 0px));
background: #fff;
border-top: 1px solid #f3f4f6;
}
</style>
+21 -9
View File
@@ -4,15 +4,15 @@
<MobileUserView v-show="!isDesktop" />
<!-- ویرایش اطلاعات — موبایل -->
<BasicActionSheet v-if="!isDesktop" v-model:show="editPassVisible">
<div class="flex justify-center justify-between">
<div class="font-bold text-lg">ویرایش اطلاعات</div>
<div class="flex flex-col justify-center items-center">
<BasicIcon :icon="isLegal.icon" size="30" :class="isLegal.color" />
<p class="text-[10px] mt-1" :class="isLegal.color">{{ isLegal.title }}</p>
<BasicActionSheet v-if="!isDesktop" v-model:show="editPassVisible" class="h-80vh">
<div class="user-edit-sheet">
<div class="user-edit-sheet__header flex justify-between items-start">
<div class="font-bold text-lg">ویرایش اطلاعات</div>
<div class="flex flex-col justify-center items-center">
<BasicIcon :icon="isLegal.icon" size="30" :class="isLegal.color" />
<p class="text-[10px] mt-1" :class="isLegal.color">{{ isLegal.title }}</p>
</div>
</div>
</div>
<div class="h60vh overflow-y-auto pb20">
<UserProfileForm show-submit />
</div>
</BasicActionSheet>
@@ -39,7 +39,7 @@
<!-- ویرایش رمزعبور — موبایل -->
<BasicActionSheet v-if="!isDesktop" v-model:show="editPasswordVisible">
<div class="font-bold text-lg">ویرایش رمزعبور</div>
<div class="h35vh overflow-y-auto">
<div class="h25vh overflow-y-auto">
<UserPasswordForm show-submit />
</div>
</BasicActionSheet>
@@ -87,6 +87,18 @@ const {
min-height: 100%;
height: 100%;
}
.user-edit-sheet {
display: flex;
flex-direction: column;
height: calc(80dvh - 3.5rem);
min-height: 0;
}
.user-edit-sheet__header {
flex-shrink: 0;
margin-bottom: 0.75rem;
}
</style>
<style lang="less">
+39 -16
View File
@@ -1,17 +1,14 @@
<template>
<div class="relative">
<div>
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
<div class="mobile-user-view">
<div class="mobile-user-view__bg" aria-hidden="true">
<img :src="img" alt="" />
</div>
<div class="bg-white w-full py-3 px-3 text-primary font-bold drop-shadow flex">
<div class="cursor-pointer" @click="router.back()">
<BasicIcon icon="vuesax-linear:arrow-right-1" />
</div>
<div class="mr-2 mt-2">اطلاعات حساب کاربری</div>
</div>
<div class="pt-16 pb-8 z-30 relative">
<MobilePageHeader title="اطلاعات حساب کاربری" show-back />
<div
class="mobile-user-view__scroll mpage-content pb-[calc(var(--app-bottom-chrome-height)+1rem)]"
>
<div
class="border-gray-200 border-1 rounded-xl p-5 trans flex flex-col items-center mx-5 z-1000 relative bg-white shadow-lg"
class="border-gray-200 border-1 rounded-xl p-5 trans flex flex-col items-center mx-5 relative bg-white shadow-lg"
>
<div class="text-primary font-bold w-full text-center flex justify-between">
نام و نام خانوادگی:
@@ -63,7 +60,7 @@
<div>ویرایش اطلاعات کاربری</div>
</div>
</BasicButton>
<div class="h-45vh overflow-y-auto mt-4">
<div class="w-full mt-4">
<BasicButton
v-for="action in menuActions"
:key="action.id"
@@ -94,7 +91,7 @@
import img from '@/assets/img/user_ly1.svg'
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import router from '@/router'
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
import { useUserPageContext } from '../composables/useUserPage'
const {
@@ -108,11 +105,37 @@ const {
</script>
<style scoped>
.relative {
.mobile-user-view {
position: relative;
z-index: 40;
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
}
.mobile-user-view__bg {
pointer-events: none;
position: absolute;
inset: 0;
overflow: hidden;
z-index: 0;
img {
position: absolute;
bottom: 0;
width: 100%;
}
}
.mobile-user-view__scroll {
position: relative;
z-index: 1;
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
max-height: 100vh;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
}
.user-menu-icon-image {
@@ -117,7 +117,7 @@
:ref="(node) => { mobileDepositScrollEl = (node as HTMLElement | null) }"
:class="loading ? 'h-screen' : ''"
class="px-3 overflow-y-scroll w-full h-[49vh] pb-16"
style="max-height: calc(100vh - 50px)"
style="max-height: var(--mpage-scroll-max-height)"
>
<list-anim v-if="!loading" :numberItemsAnim="4">
<Item v-for="item in depositItems" :key="item.id" :item="item" />