changeof UI
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
@@ -259,14 +259,23 @@
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
/* صفحات احراز هویت: ستون موبایل در وسط دسکتاپ */
|
||||
.app-shell--no-nav.app-shell--immersive {
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #141210;
|
||||
}
|
||||
|
||||
.app-shell--no-nav.app-shell--immersive .app-layout,
|
||||
.app-shell--no-nav.app-shell--immersive .app-frame {
|
||||
max-height: none;
|
||||
max-width: 430px;
|
||||
width: min(100%, 430px);
|
||||
height: 100%;
|
||||
max-height: 100dvh;
|
||||
margin-inline: auto;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.app-shell--no-nav .app-layout,
|
||||
|
||||
@@ -9,6 +9,7 @@ const route = useRoute()
|
||||
|
||||
const showNav = computed(() => {
|
||||
const noNavRoutes = [
|
||||
'welcome',
|
||||
'login',
|
||||
'register',
|
||||
'otp',
|
||||
@@ -34,7 +35,11 @@ const isWideGuest = computed(() => {
|
||||
})
|
||||
|
||||
const isImmersiveAuth = computed(
|
||||
() => route.name === 'login' || route.name === 'register' || route.name === 'otp',
|
||||
() =>
|
||||
route.name === 'welcome' ||
|
||||
route.name === 'login' ||
|
||||
route.name === 'register' ||
|
||||
route.name === 'otp',
|
||||
)
|
||||
</script>
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@ import { getCachedUser, isAuthenticated } from '@/services/authService'
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/welcome',
|
||||
name: 'welcome',
|
||||
component: () => import('@/views/auth/WelcomeView.vue'),
|
||||
meta: { guest: true, hideNav: true },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
type FieldErrors,
|
||||
} from '@/utils/formErrors'
|
||||
import fabricUrl from '@/assets/images/login-fabric.jpg'
|
||||
import fabricUrl2 from '@/assets/images/login-fabric2.png'
|
||||
|
||||
const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
@@ -89,6 +90,7 @@ onMounted(async () => {
|
||||
<template>
|
||||
<div class="page login-page">
|
||||
<img class="login-page__bg" :src="fabricUrl" alt="" />
|
||||
<img class="login-page__fabric" :src="fabricUrl2" alt="" />
|
||||
|
||||
<div class="login-page__scroll">
|
||||
<div class="login-page__stage">
|
||||
@@ -219,6 +221,21 @@ onMounted(async () => {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* پارچه پایین صفحه — پشت باکس لاگین، نه روی آن */
|
||||
.login-page__fabric {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 3;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center bottom;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.login-page__scroll {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@@ -292,7 +309,7 @@ onMounted(async () => {
|
||||
padding: 22px 18px 16px;
|
||||
border: none;
|
||||
border-radius: 28px;
|
||||
background: #f4f1ed;
|
||||
background: #ebe4dc;
|
||||
box-shadow: 0 18px 40px rgba(12, 10, 8, 0.22);
|
||||
color: #2a2622;
|
||||
}
|
||||
@@ -328,8 +345,8 @@ onMounted(async () => {
|
||||
margin-top: 18px;
|
||||
padding: 0 8px 0 14px;
|
||||
border: 1px solid #e4e0db;
|
||||
border-radius: 999px;
|
||||
background: #f7f5f1;
|
||||
border-radius: 14px;
|
||||
background: #e4ddd4;
|
||||
}
|
||||
|
||||
.phone-field.is-invalid {
|
||||
|
||||
@@ -359,10 +359,11 @@ onMounted(() => {
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
max-width: 360px;
|
||||
max-width: 390px;
|
||||
margin-inline: auto;
|
||||
padding: calc(10px + env(safe-area-inset-top, 0px)) 16px
|
||||
calc(14px + env(safe-area-inset-bottom, 0px));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.otp-top {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import FormErrorBanner from '@/components/ui/FormErrorBanner.vue'
|
||||
import IconBuilding from '@/components/icons/IconBuilding.vue'
|
||||
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
|
||||
import IconDiamond from '@/components/icons/IconDiamond.vue'
|
||||
import IconPhone from '@/components/icons/IconPhone.vue'
|
||||
@@ -216,7 +215,7 @@ async function submit() {
|
||||
@click="jobOpen = !jobOpen"
|
||||
>
|
||||
<span class="reg-field__meta">
|
||||
<IconBuilding :size="18" color="#8A847C" />
|
||||
<BasicIcon icon="vuesax-linear:category" :size="18" color="#8A847C" />
|
||||
<span :class="{ 'is-placeholder': !jobCategory }">{{ selectedJobLabel }}</span>
|
||||
</span>
|
||||
<svg class="job-chevron" viewBox="0 0 12 12" aria-hidden="true">
|
||||
@@ -275,24 +274,24 @@ async function submit() {
|
||||
</label>
|
||||
<p v-if="fieldErrors.terms" class="reg-field__error">{{ fieldErrors.terms }}</p>
|
||||
</form>
|
||||
|
||||
<section class="register-perks" aria-label="مزایا">
|
||||
<article class="register-perk">
|
||||
<IconVerified :size="22" color="#6F6B66" />
|
||||
<strong>اطمینان از اصالت محصولات</strong>
|
||||
</article>
|
||||
<article class="register-perk">
|
||||
<BasicIcon icon="vuesax-linear:truck-time" :size="22" color="#6F6B66" />
|
||||
<strong>دسترسی سریع به کالیتههای جدید</strong>
|
||||
</article>
|
||||
<article class="register-perk">
|
||||
<IconDiamond :size="22" color="#6F6B66" />
|
||||
<strong>تجربه خرید ویژه مشتریان</strong>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<div class="register-foot">
|
||||
<img class="register-foot__bg" :src="cardUrl" alt="" />
|
||||
|
||||
<section class="register-perks" aria-label="مزایا">
|
||||
<article class="register-perk">
|
||||
<IconVerified :size="22" color="#6F6B66" />
|
||||
<strong>اطمینان از اصالت محصولات</strong>
|
||||
</article>
|
||||
<article class="register-perk">
|
||||
<BasicIcon icon="vuesax-linear:truck-time" :size="22" color="#6F6B66" />
|
||||
<strong>دسترسی سریع به کالیتههای جدید</strong>
|
||||
</article>
|
||||
<article class="register-perk">
|
||||
<IconDiamond :size="22" color="#6F6B66" />
|
||||
<strong>تجربه خرید ویژه مشتریان</strong>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<p class="register-foot__copy">همراه حرفهای<br />کسبوکار شما</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -322,6 +321,7 @@ async function submit() {
|
||||
max-width: 390px;
|
||||
margin-inline: auto;
|
||||
padding: calc(10px + env(safe-area-inset-top, 0px)) 20px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.register-top {
|
||||
@@ -383,9 +383,9 @@ async function submit() {
|
||||
height: 52px;
|
||||
margin-top: 10px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #e6e1db;
|
||||
border-radius: 999px;
|
||||
background: #fbfaf7;
|
||||
border: 1px solid #e0d9d0;
|
||||
border-radius: 14px;
|
||||
background: #ebe4dc;
|
||||
}
|
||||
|
||||
.reg-field.is-invalid,
|
||||
@@ -619,13 +619,15 @@ async function submit() {
|
||||
|
||||
.register-perks {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
margin-bottom: 20rem;
|
||||
margin: 35px 0 -20px;
|
||||
padding: 16px 10px 14px;
|
||||
border-radius: 22px;
|
||||
background: #f7f3ee;
|
||||
background: #ebe4dc;
|
||||
box-shadow: 0 10px 28px rgba(40, 32, 24, 0.12), 0 2px 8px rgba(40, 32, 24, 0.06);
|
||||
}
|
||||
|
||||
.register-perk {
|
||||
@@ -645,11 +647,14 @@ async function submit() {
|
||||
|
||||
.register-foot {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: auto;
|
||||
margin-inline: -20px;
|
||||
min-height: 270px;
|
||||
min-height: 260px;
|
||||
overflow: hidden;
|
||||
padding: 20px 20px calc(20px + env(safe-area-inset-bottom, 0px));
|
||||
padding: 48px 0 calc(16px + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.register-foot__bg {
|
||||
@@ -662,8 +667,8 @@ async function submit() {
|
||||
object-position: 88% 32%;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
mask-image: linear-gradient(to bottom, transparent 0%, #000 38%);
|
||||
-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 38%);
|
||||
mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
|
||||
-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
|
||||
}
|
||||
|
||||
.register-foot::before {
|
||||
@@ -672,16 +677,16 @@ async function submit() {
|
||||
|
||||
.register-foot__copy {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
z-index: 1;
|
||||
left: 24px;
|
||||
top: 8.75rem;
|
||||
top: 38%;
|
||||
margin: 0;
|
||||
max-width: 10rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.55;
|
||||
text-align: right;
|
||||
color: #5a5550;
|
||||
color:#1c1b19;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
|
||||
import IconQemashMark from '@/components/icons/IconQemashMark.vue'
|
||||
import fabricUrl from '@/assets/images/login-fabric.jpg'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
/* ترتیب DOM از راست به چپ در RTL: ستاره → کامیون → لایهها */
|
||||
const features = [
|
||||
{
|
||||
icon: 'star',
|
||||
title: 'همراه همیشگی کسبوکارتان',
|
||||
subtitle: 'با خدمات ویژه مشتریان',
|
||||
},
|
||||
{
|
||||
icon: 'vuesax-linear:truck-time',
|
||||
title: 'سفارش عمده',
|
||||
subtitle: 'مستقیم از تولیدکننده',
|
||||
},
|
||||
{
|
||||
icon: 'vuesax-linear:element-3',
|
||||
title: 'تنوع بینظیر محصولات',
|
||||
subtitle: 'از کلاسیک تا مدرن',
|
||||
},
|
||||
] as const
|
||||
|
||||
function goLogin() {
|
||||
const redirect = typeof router.currentRoute.value.query.redirect === 'string'
|
||||
? router.currentRoute.value.query.redirect
|
||||
: undefined
|
||||
router.push({
|
||||
name: 'login',
|
||||
query: redirect ? { redirect } : undefined,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page welcome-page">
|
||||
<img class="welcome-page__bg" :src="fabricUrl" alt="" />
|
||||
<div class="welcome-page__veil" aria-hidden="true" />
|
||||
|
||||
<div class="welcome-page__scroll">
|
||||
<div class="welcome-page__stage">
|
||||
<header class="welcome-top">
|
||||
<button type="button" class="welcome-skip" @click="goLogin">رد شدن</button>
|
||||
</header>
|
||||
|
||||
<div class="welcome-brand">
|
||||
<IconQemashMark :size="88" />
|
||||
<h1 class="welcome-brand__fa">نادمی تکس</h1>
|
||||
<p class="welcome-brand__tag">انتخاب حرفهای، شروع یک همکاری ماندگار</p>
|
||||
<span class="welcome-brand__rule" aria-hidden="true" />
|
||||
</div>
|
||||
|
||||
<ul class="welcome-features">
|
||||
<li v-for="item in features" :key="item.title" class="welcome-feature">
|
||||
<span class="welcome-feature__icon" aria-hidden="true">
|
||||
<svg
|
||||
v-if="item.icon === 'star'"
|
||||
class="welcome-feature__star"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"
|
||||
stroke="#fff"
|
||||
stroke-width="1.5"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<BasicIcon v-else :icon="item.icon" :size="22" color="#ffffff" />
|
||||
</span>
|
||||
<strong>{{ item.title }}</strong>
|
||||
<span>{{ item.subtitle }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="welcome-spacer" aria-hidden="true" />
|
||||
|
||||
<div class="welcome-dots" aria-hidden="true">
|
||||
<i class="is-on" />
|
||||
<i />
|
||||
<i />
|
||||
<i />
|
||||
</div>
|
||||
|
||||
<button type="button" class="welcome-cta" @click="goLogin">
|
||||
<span>ورود / ثبتنام</span>
|
||||
<span class="welcome-cta__chevron" aria-hidden="true">
|
||||
<IconChevronLeft :size="18" color="#ffffff" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.welcome-page {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
color: #f4ede4;
|
||||
background: #1a1612;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.welcome-page__bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.welcome-page__veil {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 1;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(12, 10, 8, 0.42) 0%, rgba(12, 10, 8, 0.28) 42%, rgba(12, 10, 8, 0.72) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.welcome-page__scroll {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.welcome-page__stage {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
max-width: 390px;
|
||||
margin-inline: auto;
|
||||
padding: calc(12px + env(safe-area-inset-top, 0px)) 20px
|
||||
calc(20px + env(safe-area-inset-bottom, 0px));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.welcome-top {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.welcome-skip {
|
||||
height: 34px;
|
||||
padding: 0 16px;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: rgba(12, 10, 8, 0.45);
|
||||
color: #f4ede4;
|
||||
font: inherit;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.welcome-brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.welcome-brand__fa {
|
||||
margin: 14px 0 0;
|
||||
font-size: 1.875rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: #ead7c0;
|
||||
}
|
||||
|
||||
.welcome-brand__tag {
|
||||
margin: 10px 0 0;
|
||||
max-width: 16rem;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.7;
|
||||
color: rgba(244, 237, 228, 0.92);
|
||||
}
|
||||
|
||||
.welcome-brand__rule {
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 1.5px;
|
||||
margin-top: 16px;
|
||||
border-radius: 1px;
|
||||
background: #c9a56a;
|
||||
}
|
||||
|
||||
.welcome-features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin: 36px 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.welcome-feature {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-feature__icon {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 999px;
|
||||
background: rgba(244, 237, 228, 0.22);
|
||||
color: #fff;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.welcome-feature__star {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.welcome-feature strong {
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.45;
|
||||
color: #f4ede4;
|
||||
}
|
||||
|
||||
.welcome-feature span {
|
||||
font-size: 0.5625rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: rgba(244, 237, 228, 0.72);
|
||||
}
|
||||
|
||||
.welcome-spacer {
|
||||
flex: 1 1 auto;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
.welcome-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.welcome-dots i {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background: rgba(244, 237, 228, 0.28);
|
||||
}
|
||||
|
||||
.welcome-dots i.is-on {
|
||||
background: #f4ede4;
|
||||
}
|
||||
|
||||
.welcome-cta {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 52px;
|
||||
padding: 0 44px;
|
||||
border: 1px solid rgba(244, 237, 228, 0.28);
|
||||
border-radius: 999px;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(20, 78, 82, 0.55) 0%, rgba(10, 53, 60, 0.42) 48%, rgba(8, 42, 48, 0.48) 100%);
|
||||
color: #fff;
|
||||
font: inherit;
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.welcome-cta__chevron {
|
||||
position: absolute;
|
||||
inset-inline-end: 16px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.welcome-page {
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.welcome-page__stage {
|
||||
max-width: 390px;
|
||||
padding-block: 16px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 359px) {
|
||||
.welcome-page__stage {
|
||||
padding-inline: 14px;
|
||||
}
|
||||
|
||||
.welcome-brand__fa {
|
||||
font-size: 1.625rem;
|
||||
}
|
||||
|
||||
.welcome-feature__icon {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user