Merge branch 'main' of https://github.com/Byeto-Company/hossein_por_shop
This commit is contained in:
@@ -1,7 +1,59 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
// types
|
||||
|
||||
type Props = {
|
||||
address?: Address;
|
||||
isSelected?: boolean;
|
||||
};
|
||||
|
||||
// props
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
// emit
|
||||
|
||||
const emit = defineEmits(["select"]);
|
||||
|
||||
// computed
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<button
|
||||
@click="!!address ? emit('select', address) : null"
|
||||
:class="
|
||||
isSelected
|
||||
? 'border-cyan-500 ring-2 ring-offset-2 ring-cyan-500'
|
||||
: 'border-gray-300'
|
||||
"
|
||||
class="flex flex-col items-center transition-all cursor-pointer w-full gap-4 p-4 border rounded-xl bg-gray-50"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-start w-full lg:text-[1.125rem] font-semibold text-gray-900"
|
||||
>
|
||||
آدرس
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="flex flex-col items-center justify-between w-full gap-4 lg:flex-row"
|
||||
>
|
||||
<span
|
||||
class="w-full text-start text-sm lg:text-[1rem] lg:w-9/12 text-gray-700"
|
||||
>
|
||||
{{
|
||||
!!address
|
||||
? `ایران, ${address.province}, ${address.city}, ${address.full_address}, کدپستی ${address.postal_code}`
|
||||
: "افزودن آدرس جدید"
|
||||
}}
|
||||
</span>
|
||||
|
||||
<div class="flex items-center justify-end w-full lg:w-3/12">
|
||||
<AddressModal
|
||||
@add="(data) => $emit('add', data)"
|
||||
:address="address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
<script setup lang="ts">
|
||||
// types
|
||||
|
||||
type Props = {
|
||||
address?: Address;
|
||||
};
|
||||
|
||||
// props
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const { address } = toRefs(props);
|
||||
|
||||
// emit
|
||||
|
||||
const emit = defineEmits(["add"]);
|
||||
|
||||
// state
|
||||
|
||||
const isShow = ref(false);
|
||||
|
||||
const addressData = ref<
|
||||
Pick<Address, "province" | "city" | "postal_code" | "full_address">
|
||||
>({
|
||||
province: address.value?.province ?? "",
|
||||
city: address.value?.city ?? "",
|
||||
postal_code: address.value?.postal_code ?? "",
|
||||
full_address: address.value?.full_address ?? "",
|
||||
});
|
||||
|
||||
// computed
|
||||
|
||||
const isEditing = computed(() => !!address.value);
|
||||
|
||||
// methods
|
||||
|
||||
const closeModal = () => {
|
||||
if (!isEditing.value) {
|
||||
addressData.value = {
|
||||
province: "",
|
||||
city: "",
|
||||
postal_code: "",
|
||||
full_address: "",
|
||||
};
|
||||
}
|
||||
isShow.value = false;
|
||||
};
|
||||
|
||||
const addNew = () => {
|
||||
emit("add", { ...addressData.value, id: Date.now() });
|
||||
closeModal();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot
|
||||
v-model:open="isShow"
|
||||
@update:open="
|
||||
(state) => {
|
||||
!state ? closeModal() : null;
|
||||
}
|
||||
"
|
||||
>
|
||||
<DialogTrigger>
|
||||
<button
|
||||
class="flex items-center gap-1 rtl:flex-row-reverse font-iran-yekan-x cursor-pointer"
|
||||
>
|
||||
<span class="font-bold text-cyan-500 text-sm lg:text-[1rem]">
|
||||
{{ !!address ? "ویرایش آدرس" : "افزودن آدرس" }}
|
||||
</span>
|
||||
<Icon
|
||||
v-if="!!address"
|
||||
name="bi:pen"
|
||||
class="**:fill-cyan-500"
|
||||
size="16"
|
||||
/>
|
||||
<Icon
|
||||
v-else
|
||||
name="bi:plus"
|
||||
class="**:stroke-cyan-500"
|
||||
size="20"
|
||||
/>
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="bg-black/20 data-[state=open]:animate-overlay-show fixed inset-0 z-30"
|
||||
/>
|
||||
<DialogContent
|
||||
class="data-[state=open]:animate-content-show text-black font-iran-yekan-x fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] max-w-[50rem] translate-x-[-50%] translate-y-[-50%] rounded-3xl bg-white shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none z-[100]"
|
||||
>
|
||||
<div
|
||||
class="w-full flex items-center px-6 justify-between py-[1.8rem] border-b border-slate-200"
|
||||
>
|
||||
<DialogClose
|
||||
class="inline-flex size-8 items-center justify-center transition-all rounded-full bg-gray-50 border border-slate-200 hover:border-black focus:outline-none"
|
||||
aria-label="Close"
|
||||
>
|
||||
<Icon name="bi:x-lg" class="**:fill-red-600" />
|
||||
</DialogClose>
|
||||
<DialogTitle class="typo-sub-h-xl font-semibold">
|
||||
{{ !!address ? "ویرایش آدرس" : "افزودن آدرس" }}
|
||||
</DialogTitle>
|
||||
</div>
|
||||
|
||||
<div class="flex-col-center gap-6 px-6 py-10" dir="rtl">
|
||||
<div
|
||||
class="grid w-full grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3"
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label
|
||||
for="province"
|
||||
class="text-xs font-semibold lg:text-sm text-gray-900"
|
||||
>استان
|
||||
<span class="text-sm text-red-500"
|
||||
>*</span
|
||||
></label
|
||||
>
|
||||
|
||||
<ComboBox
|
||||
id="province"
|
||||
:options="[
|
||||
{
|
||||
name: 'استان ها',
|
||||
children: [
|
||||
{ name: 'مشهد' },
|
||||
{ name: 'مشهد' },
|
||||
{ name: 'مشهد' },
|
||||
],
|
||||
},
|
||||
]"
|
||||
v-model="addressData.province"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<label
|
||||
for="city"
|
||||
class="text-xs font-semibold lg:text-sm text-gray-900"
|
||||
>شهر
|
||||
<span class="text-sm text-red-500"
|
||||
>*</span
|
||||
></label
|
||||
>
|
||||
<ComboBox
|
||||
id="city"
|
||||
:options="[
|
||||
{
|
||||
name: 'استان ها',
|
||||
children: [
|
||||
{ name: 'مشهد' },
|
||||
{ name: 'مشهد' },
|
||||
{ name: 'مشهد' },
|
||||
],
|
||||
},
|
||||
]"
|
||||
v-model="addressData.city"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<label
|
||||
for="post"
|
||||
class="text-xs font-semibold lg:text-sm text-gray-900"
|
||||
>کد پستی
|
||||
<span class="text-sm text-red-500"
|
||||
>*</span
|
||||
></label
|
||||
>
|
||||
<Input
|
||||
id="post"
|
||||
type="text"
|
||||
placeholder="جست و جو"
|
||||
class="rounded-xl"
|
||||
v-model="addressData.postal_code"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col w-full gap-2">
|
||||
<label
|
||||
for="address"
|
||||
class="text-xs font-semibold lg:text-sm text-gray-900"
|
||||
>آدرس کامل
|
||||
<span class="text-sm text-red-500">*</span></label
|
||||
>
|
||||
<textarea
|
||||
id="address"
|
||||
placeholder="آدرس خود را بنویسید"
|
||||
v-model="addressData.full_address"
|
||||
class="flex items-center field-sizing-content resize-none bg-slate-50 border-slate-200 hover:border-black max-h-[10rem] text-black justify-between cursor-text transition-all border-[1.5px] gap-3 typo-label-md px-4 py-3.5 selection:bg-slate-100 rounded-100 outline-none flex-1 text-sm placeholder-slate-400"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 border-t border-slate-200 flex gap-3">
|
||||
<Button @click="addNew" class="rounded-full px-10"
|
||||
>ثبت</Button
|
||||
>
|
||||
<DialogClose aria-label="Close">
|
||||
<Button variant="outlined" class="rounded-full px-10">
|
||||
انصراف
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</DialogRoot>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -17,7 +17,7 @@ const handleDeleteFromCart = () => {};
|
||||
class="size-[88px] aspect-square shrink-0 rounded-100 border border-gray-300 overflow-hidden"
|
||||
>
|
||||
<img
|
||||
src="../assets/images/products/product-1.png"
|
||||
src="/img/product-1.jpg"
|
||||
class="object-cover size-full"
|
||||
alt="product"
|
||||
/>
|
||||
@@ -47,13 +47,13 @@ const handleDeleteFromCart = () => {};
|
||||
>
|
||||
<Icon
|
||||
v-if="counter == 1"
|
||||
name="bi:dash"
|
||||
class="**:stroke-gray-800"
|
||||
name="bi:trash"
|
||||
class="**:fill-red-700"
|
||||
/>
|
||||
<Icon
|
||||
v-else
|
||||
name="bi:trash"
|
||||
class="**:fill-red-700"
|
||||
name="bi:dash"
|
||||
class="**:stroke-gray-800"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<div class="flex items-center w-full gap-4">
|
||||
<div
|
||||
class="size-[3.5rem] shrink-0 rounded-100 border border-gray-300 overflow-hidden"
|
||||
>
|
||||
<img src="/img/product-1.jpg" alt="product" class="object-conver" />
|
||||
</div>
|
||||
<span
|
||||
class="text-xs font-semibold lg:text-sm text-gray-800 line-clamp-2"
|
||||
>
|
||||
فشارسنج بازویی امرن Omron M3
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -9,11 +9,14 @@ type Option = {
|
||||
type Props = {
|
||||
options: Option[];
|
||||
modelValue: string[];
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
// props
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: "جست و جو",
|
||||
});
|
||||
|
||||
const { modelValue } = toRefs(props);
|
||||
|
||||
@@ -48,11 +51,11 @@ watch(
|
||||
<template>
|
||||
<ComboboxRoot class="relative" dir="rtl" v-model="value">
|
||||
<ComboboxAnchor
|
||||
class="w-full inline-flex items-center justify-between rounded-full border border-slate-200 hover:border-slate-300 focus:border-slate-800 px-[1rem] text-sm leading-none py-3.5 gap-[5px] bg-slate-50 text-black hover:bg-white/90 transition-all data-[placeholder]:text-black/80 typo-label-sm outline-none"
|
||||
class="w-full inline-flex items-center justify-between rounded-xl border-[1.5px] border-slate-200 focus:border-slate-800 px-[1rem] text-sm leading-none py-3.5 gap-[5px] bg-slate-50 text-black hover:border-black transition-all data-[placeholder]:text-black/80 typo-label-sm outline-none"
|
||||
>
|
||||
<ComboboxInput
|
||||
class="!bg-transparent outline-none text-black h-full selection:bg-slate-100 placeholder-stone-400"
|
||||
placeholder="جست و جوی دسته بندی"
|
||||
class="!bg-transparent outline-none text-black h-full selection:bg-slate-100 placeholder-slate-400"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
<ComboboxTrigger>
|
||||
<Icon name="ci:chevron-down" class="size-5" />
|
||||
@@ -60,7 +63,7 @@ watch(
|
||||
</ComboboxAnchor>
|
||||
|
||||
<ComboboxContent
|
||||
class="absolute z-10 w-full mt-1.5 bg-slate-50 overflow-hidden rounded-3xl shadow-sm border border-slate-200 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=bottom]:animate-slideUpAndFade"
|
||||
class="absolute z-10 w-full mt-1.5 bg-slate-50 overflow-hidden rounded-xl shadow-sm border border-slate-200 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=bottom]:animate-slideUpAndFade"
|
||||
>
|
||||
<ComboboxViewport class="p-[1rem]">
|
||||
<ComboboxEmpty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
type Props = {
|
||||
variant?: "solid" | "outlined";
|
||||
disabled?: boolean;
|
||||
@@ -12,7 +11,7 @@ type Props = {
|
||||
// props
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
variant: "solid"
|
||||
variant: "solid",
|
||||
});
|
||||
const { variant, message, error, disabled } = toRefs(props);
|
||||
|
||||
@@ -28,15 +27,15 @@ const inputRef = ref<HTMLInputElement | null>(null);
|
||||
|
||||
const classes = computed(() => {
|
||||
return [
|
||||
"flex items-center justify-between cursor-text transition-all border-[1.5px] gap-3 typo-label-md px-4 py-3 rounded-100",
|
||||
"flex items-center text-black justify-between cursor-text transition-all border-[1.5px] gap-3 typo-label-md px-4 py-3.5 selection:bg-slate-100 rounded-100",
|
||||
{
|
||||
"input-solid": variant.value === "solid",
|
||||
"input-outlined": variant.value === "outlined",
|
||||
"input-effects": !error.value,
|
||||
[variant.value === "solid"
|
||||
? "input-solid-error"
|
||||
: "input-outlined-error"]: error.value
|
||||
}
|
||||
: "input-outlined-error"]: error.value,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
@@ -45,7 +44,6 @@ const classes = computed(() => {
|
||||
const onInput = (e: any) => {
|
||||
emit("update:modelValue", e.target.value);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -56,7 +54,7 @@ const onInput = (e: any) => {
|
||||
:value="modelValue"
|
||||
@input="onInput"
|
||||
ref="inputRef"
|
||||
class="outline-none flex-1"
|
||||
class="outline-none flex-1 text-sm placeholder-slate-400"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ const onSwiper = (swiper: SwiperClass) => {
|
||||
<template>
|
||||
<section class="w-full flex flex-col gap-[4rem] px-0 py-[5rem] container">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<span class="text-black typo-h-3">
|
||||
<span class="text-black typo-h-4">
|
||||
{{ title }}
|
||||
</span>
|
||||
<div class="flex-center gap-[.5rem]">
|
||||
|
||||
@@ -95,6 +95,22 @@ const nextPage = computed(() => route.meta.nextPage);
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label
|
||||
v-if="route.name == 'cart-checkout'"
|
||||
class="flex items-center w-full group gap-2 p-3 my-5 text-sm transition-all border text-gray-600 focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-cyan-500 bg-gray-50 border-gray-200 rounded-100"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="کد تخفیف"
|
||||
class="w-full border-none focus:border-none focus:outline-none placeholder:text-gray-600 h-[22px]"
|
||||
/>
|
||||
<button
|
||||
class="ring ring-offset-[-4px] active:ring-offset-2 transition-all duration-75 font-bold text-cyan-500 rounded-50"
|
||||
>
|
||||
ثبت
|
||||
</button>
|
||||
</label>
|
||||
|
||||
<NuxtLink :to="{ name: nextPage.name }">
|
||||
<Button
|
||||
start-icon="bi:arrow-right"
|
||||
|
||||
@@ -1,14 +1,116 @@
|
||||
<script setup lang="ts">
|
||||
// meta
|
||||
|
||||
definePageMeta({
|
||||
layout: "cart",
|
||||
pageTitle: "ثبت سفارش",
|
||||
prevPage: { name: "cart-delivery", label: "انتخاب آدرس" },
|
||||
nextPage: { name: "checkout", label: "پرداخت" },
|
||||
});
|
||||
|
||||
// types
|
||||
|
||||
type PaymentGateway = {
|
||||
id: number;
|
||||
picture: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
// state
|
||||
|
||||
const paymentGateways = ref<PaymentGateway[]>([
|
||||
{
|
||||
id: 1,
|
||||
picture: "/zarinpal.png",
|
||||
title: "زرین پال",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
picture: "/saman-bank.png",
|
||||
title: "بانک سامان",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
picture: "/mellat-bank.png",
|
||||
title: "بانک ملت",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
picture: "/jibimo.png",
|
||||
title: "جیبی مو",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
picture: "/idpay.png",
|
||||
title: "آی دی پی",
|
||||
},
|
||||
]);
|
||||
|
||||
const selectedGateway = ref<PaymentGateway>(paymentGateways.value[0]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<div class="flex flex-col w-full gap-5">
|
||||
<div
|
||||
class="flex flex-col items-center w-full gap-4 p-4 border border-gray-300 rounded-xl bg-gray-50"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-start w-full text-[1.125rem] font-semibold text-gray-900"
|
||||
>
|
||||
روش پرداخت
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="w-full grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4"
|
||||
>
|
||||
<div
|
||||
v-for="(gateway, index) in paymentGateways"
|
||||
@click="selectedGateway = { ...gateway }"
|
||||
:key="index"
|
||||
:class="
|
||||
selectedGateway.id == gateway.id
|
||||
? 'ring-2 ring-offset-2 ring-cyan-500 border-cyan-500'
|
||||
: 'border-slate-200'
|
||||
"
|
||||
class="w-full p-5 border rounded-xl flex flex-col gap-4 transition-all cursor-pointer"
|
||||
>
|
||||
<div class="aspect-square flex-center">
|
||||
<img :src="gateway.picture" class="object-cover" />
|
||||
</div>
|
||||
<span class="typo-label-sm text-black">
|
||||
{{ gateway.title }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col items-center w-full gap-4 p-4 border lg:gap-6 border-gray-300 rounded-xl bg-gray-50"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-start w-full lg:text-[1.125rem] font-semibold text-gray-900"
|
||||
>
|
||||
خلاصه سفارش
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="grid w-full grid-cols-1 gap-6 lg:grid-cols-3 md:grid-cols-2"
|
||||
>
|
||||
<MinimalCartItem v-for="i in 9" />
|
||||
|
||||
<div class="h-7 flex-center col-span-full lg:hidden">
|
||||
<button class="gap-2 flex-center">
|
||||
<span class="text-sm font-bold text-cyan-500">
|
||||
مشاهده بیشتر
|
||||
</span>
|
||||
<Icon
|
||||
name="bi:chevron-down"
|
||||
class="**:stroke-cyan-500"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,14 +1,178 @@
|
||||
<script setup lang="ts">
|
||||
// meta
|
||||
|
||||
definePageMeta({
|
||||
layout: "cart",
|
||||
pageTitle: "انتخاب آدرس",
|
||||
prevPage: { name: "cart", label: "سبد خرید" },
|
||||
nextPage: { name: "cart-checkout", label: "تسویه حساب" },
|
||||
});
|
||||
|
||||
// types
|
||||
|
||||
type DeliveryData = {
|
||||
address: Address | null;
|
||||
deliveryMethod: {
|
||||
tipax: boolean;
|
||||
pishtaz: boolean;
|
||||
peyk: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
// state
|
||||
|
||||
const addresses = ref<Address[]>([]);
|
||||
|
||||
const deliveryData = ref<DeliveryData>({
|
||||
address: null,
|
||||
deliveryMethod: {
|
||||
peyk: false,
|
||||
pishtaz: true,
|
||||
tipax: false,
|
||||
},
|
||||
});
|
||||
|
||||
// methods
|
||||
|
||||
const handleAddNewAddress = (address: Address) => {
|
||||
addresses.value.push(address);
|
||||
};
|
||||
|
||||
const handleSelectAddress = (address: Address) => {
|
||||
deliveryData.value.address = { ...address };
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col w-full gap-6"></div>
|
||||
<div class="flex flex-col w-full gap-5">
|
||||
<AddressItem @add="handleAddNewAddress" />
|
||||
<div v-if="addresses.length > 0" class="flex flex-col w-full gap-6">
|
||||
<span class="typo-sub-h-xl"> آدرس های شما </span>
|
||||
<div class="flex flex-col gap-6 w-full">
|
||||
<AddressItem
|
||||
v-for="(address, index) in addresses"
|
||||
:key="index"
|
||||
:address="address"
|
||||
@select="handleSelectAddress"
|
||||
:isSelected="address.id == deliveryData.address?.id"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-col items-center w-full gap-4 p-4 border border-gray-300 rounded-xl bg-gray-50"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-start w-full lg:text-[1.125rem] font-semibold text-gray-900"
|
||||
>
|
||||
زمان و شیوه ارسال
|
||||
</span>
|
||||
|
||||
<label
|
||||
@click="deliveryData.deliveryMethod.pishtaz = true"
|
||||
:class="
|
||||
deliveryData.deliveryMethod.pishtaz
|
||||
? 'ring-cyan-500 ring-offset-2 ring-2'
|
||||
: ''
|
||||
"
|
||||
class="flex flex-col select-none w-full gap-2 p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-cyan-500 ring-offset-2 focus-within:border-cyan-500 rounded-100 border-gray-300 bg-gray-50"
|
||||
>
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<SwitchRoot
|
||||
v-model="deliveryData.deliveryMethod.pishtaz"
|
||||
:defaultValue="false"
|
||||
class="w-[3rem] h-[1.8rem] shrink-0 flex data-[state=unchecked]:bg-slate-200 data-[state=checked]:bg-cyan-500 border border-slate-300 data-[state=checked]:border-cyan-800/20 rounded-full relative transition-all focus-within:outline-none"
|
||||
>
|
||||
<SwitchThumb
|
||||
class="size-6 my-auto bg-white text-sm ms-1 flex items-center justify-center shadow-xl rounded-full transition-transform translate-x-0.5 will-change-transform data-[state=checked]:-translate-x-[68%]"
|
||||
/>
|
||||
</SwitchRoot>
|
||||
<span
|
||||
class="w-full text-gray-800 text-sm lg:text-[1rem]"
|
||||
>پست پیشتاز</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<span class="text-gray-800 text-sm lg:text-[1rem]">
|
||||
۱۵۰٬۰۰۰ تومان
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label
|
||||
class="flex items-center opacity-50 select-none pointer-events-none justify-between w-full p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-cyan-500 ring-offset-2 focus-within:border-cyan-500 rounded-100 border-gray-300 bg-gray-50"
|
||||
>
|
||||
<div class="flex items-center gap-2.5">
|
||||
<SwitchRoot
|
||||
v-model="deliveryData.deliveryMethod.tipax"
|
||||
class="w-[3rem] h-[1.8rem] shrink-0 flex data-[state=unchecked]:bg-slate-200 data-[state=checked]:bg-cyan-500 border border-slate-300 data-[state=checked]:border-cyan-800/20 rounded-full relative transition-all focus-within:outline-none"
|
||||
>
|
||||
<SwitchThumb
|
||||
class="size-6 my-auto bg-white text-sm ms-1 flex items-center justify-center shadow-xl rounded-full transition-transform translate-x-0.5 will-change-transform data-[state=checked]:-translate-x-[68%]"
|
||||
/>
|
||||
</SwitchRoot>
|
||||
<span class="w-full text-gray-800 text-sm lg:text-[1rem]"
|
||||
>تیپاکس</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<span class="text-gray-800 text-sm lg:text-[1rem]">
|
||||
۱۵۰٬۰۰۰ تومان
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label
|
||||
class="flex items-center opacity-50 select-none pointer-events-none justify-between w-full p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-cyan-500 ring-offset-2 focus-within:border-cyan-500 rounded-100 border-gray-300 bg-gray-50"
|
||||
>
|
||||
<div class="flex items-center gap-2.5">
|
||||
<SwitchRoot
|
||||
v-model="deliveryData.deliveryMethod.peyk"
|
||||
class="w-[3rem] h-[1.8rem] shrink-0 flex data-[state=unchecked]:bg-slate-200 data-[state=checked]:bg-cyan-500 border border-slate-300 data-[state=checked]:border-cyan-800/20 rounded-full relative transition-all focus-within:outline-none"
|
||||
>
|
||||
<SwitchThumb
|
||||
class="size-6 my-auto bg-white text-sm ms-1 flex items-center justify-center shadow-xl rounded-full transition-transform translate-x-0.5 will-change-transform data-[state=checked]:-translate-x-[68%]"
|
||||
/>
|
||||
</SwitchRoot>
|
||||
<span class="w-full text-gray-800 text-sm lg:text-[1rem]"
|
||||
>ارسال با پیک (فقط ارسال درون شهری شیراز)</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<span class="text-gray-800 text-sm lg:text-[1rem]">
|
||||
۱۵۰٬۰۰۰ تومان
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-col items-center w-full gap-4 p-4 border lg:gap-6 border-gray-300 rounded-xl bg-gray-50"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-start w-full lg:text-[1.125rem] font-semibold text-gray-900"
|
||||
>
|
||||
خلاصه سفارش
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="grid w-full grid-cols-1 gap-6 lg:grid-cols-3 md:grid-cols-2"
|
||||
>
|
||||
<MinimalCartItem v-for="i in 9" />
|
||||
|
||||
<div class="h-7 flex-center col-span-full lg:hidden">
|
||||
<button class="gap-2 flex-center">
|
||||
<span class="text-sm font-bold text-cyan-500">
|
||||
مشاهده بیشتر
|
||||
</span>
|
||||
<Icon
|
||||
name="bi:chevron-down"
|
||||
class="**:stroke-cyan-500"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 291 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 498 KiB |
Vendored
+43
-29
@@ -9,38 +9,52 @@ declare global {
|
||||
};
|
||||
|
||||
type Chat = {
|
||||
id: number,
|
||||
sender: "ai" | "user",
|
||||
content: string
|
||||
}
|
||||
id: number;
|
||||
sender: "ai" | "user";
|
||||
content: string;
|
||||
};
|
||||
|
||||
type Product = {
|
||||
"id": number,
|
||||
"price": number,
|
||||
"name": string,
|
||||
"description": string,
|
||||
"currency": string,
|
||||
"image": string,
|
||||
"rating": number,
|
||||
"view": number,
|
||||
"sell": number,
|
||||
"in_stock": number,
|
||||
"discount": number,
|
||||
"slug": string,
|
||||
"meta_description": string | null,
|
||||
"meta_keywords": null,
|
||||
"meta_rating": number | null
|
||||
}
|
||||
id: number;
|
||||
price: number;
|
||||
name: string;
|
||||
description: string;
|
||||
currency: string;
|
||||
image: string;
|
||||
rating: number;
|
||||
view: number;
|
||||
sell: number;
|
||||
in_stock: number;
|
||||
discount: number;
|
||||
slug: string;
|
||||
meta_description: string | null;
|
||||
meta_keywords: null;
|
||||
meta_rating: number | null;
|
||||
};
|
||||
|
||||
type Category = {
|
||||
"id": number,
|
||||
"name": string,
|
||||
"slug": string,
|
||||
"icon": string,
|
||||
"meta_title": string,
|
||||
"meta_description": string,
|
||||
"parent": number,
|
||||
"children": "string"
|
||||
}
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
icon: string;
|
||||
meta_title: string;
|
||||
meta_description: string;
|
||||
parent: number;
|
||||
children: "string";
|
||||
};
|
||||
|
||||
type Address = {
|
||||
id: number;
|
||||
province: string;
|
||||
city: string;
|
||||
postal_code: string;
|
||||
full_address: string;
|
||||
};
|
||||
|
||||
type DeliveryMethod = {
|
||||
type: string;
|
||||
date: string;
|
||||
hour: string;
|
||||
price: string;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user