final commit before execution
This commit is contained in:
@@ -94,7 +94,7 @@ export default function LoginForm() {
|
||||
</div>
|
||||
<FormError message={error} />
|
||||
<Button type='submit' className='w-full' disabled={loading}>
|
||||
{loading ? 'Loading...' : 'Login'}
|
||||
{loading ? 'Loading...' : 'Увійти'}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@@ -23,65 +23,64 @@ export default function CartItems() {
|
||||
removeItemFromCart(productId)
|
||||
}
|
||||
|
||||
if (cartItems && cartItems.length < 1) {
|
||||
if (cartItems && cartItems.length > 0) {
|
||||
return (
|
||||
<div className='flex h-72 flex-col items-center justify-center'>
|
||||
<h2 className='mb-5 mt-10 text-3xl font-bold'>Cart is Empty</h2>
|
||||
<Link
|
||||
href={'/catalog'}
|
||||
className='rounded-md bg-orange-500 px-6 py-2 text-white'
|
||||
>
|
||||
Shop
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{cartItems?.map((item: CartItem, i: number) => (
|
||||
<div className='my-4 flex items-center' key={i}>
|
||||
<div className='col'>
|
||||
{item.title}
|
||||
<Image
|
||||
src={(item?.image || '').replace('.jpg', '-thumb.jpg')}
|
||||
alt=''
|
||||
width={96}
|
||||
height={96}
|
||||
className='rounded-md border'
|
||||
style={{
|
||||
width: '96px',
|
||||
height: '96px',
|
||||
objectFit: 'cover'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-none'>
|
||||
<div className='flex w-16 flex-none items-center justify-center'>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
className='rounded-0 h-[3rem] w-[3rem] text-2xl leading-none text-brand-violet'
|
||||
onClick={() => onDecreaseQuantity(item.id)}
|
||||
>
|
||||
<Minus />
|
||||
</Button>
|
||||
<div className='mx-4 text-xl font-bold leading-none text-brand-violet'>
|
||||
{item.quantity}
|
||||
<>
|
||||
{cartItems?.map((item: CartItem, i: number) => (
|
||||
<div className='my-4 flex items-center' key={i}>
|
||||
<div className='col'>
|
||||
{item.title}
|
||||
<Image
|
||||
src={(item?.image || '').replace('.jpg', '-thumb.jpg')}
|
||||
alt=''
|
||||
width={96}
|
||||
height={96}
|
||||
className='rounded-md border'
|
||||
style={{
|
||||
width: '96px',
|
||||
height: '96px',
|
||||
objectFit: 'cover'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-none'>
|
||||
<div className='flex w-16 flex-none items-center justify-center'>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
className='rounded-0 h-[3rem] w-[3rem] text-2xl leading-none text-brand-violet'
|
||||
onClick={() => onDecreaseQuantity(item.id)}
|
||||
>
|
||||
<Minus />
|
||||
</Button>
|
||||
<div className='mx-4 text-xl font-bold leading-none text-brand-violet'>
|
||||
{item.quantity}
|
||||
</div>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
className='rounded-0 h-[3rem] w-[3rem] text-2xl leading-none text-brand-violet'
|
||||
onClick={() => onIncreaseQuantity(item.id)}
|
||||
>
|
||||
<Plus />
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
className='rounded-0 h-[3rem] w-[3rem] text-2xl leading-none text-brand-violet'
|
||||
onClick={() => onIncreaseQuantity(item.id)}
|
||||
>
|
||||
<Plus />
|
||||
</Button>
|
||||
</div>
|
||||
<div className='col text-right text-lg font-bold'>
|
||||
{(item.price * item.quantity).toFixed(2)} грн
|
||||
</div>
|
||||
</div>
|
||||
<div className='col text-right text-lg font-bold'>
|
||||
{(item.price * item.quantity).toFixed(2)} грн
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className='flex h-72 flex-col items-center justify-center'>
|
||||
<h2 className='mb-5 mt-10 text-3xl font-bold'>Cart is Empty</h2>
|
||||
<Link
|
||||
href={'/catalog'}
|
||||
className='rounded-md bg-orange-500 px-6 py-2 text-white'
|
||||
>
|
||||
Продовжити покупки
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export default function ProductCarousel({
|
||||
selected={index === selectedIndex}
|
||||
index={index}
|
||||
/>
|
||||
<DialogContent className='overflow w-full'>
|
||||
<DialogContent className='overflow max-w-screen rounded-0 h-screen p-0'>
|
||||
<Image
|
||||
src={image.uri}
|
||||
alt=''
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {ProductResource} from '@prisma/client'
|
||||
import {getProductByIdWitData} from '@prisma/client/sql'
|
||||
import {ChevronDown, ChevronsUpDown} from 'lucide-react'
|
||||
import {getTranslations} from 'next-intl/server'
|
||||
import {notFound} from 'next/navigation'
|
||||
|
||||
@@ -13,10 +14,20 @@ import {
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator
|
||||
} from '@/components/ui/breadcrumb'
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger
|
||||
} from '@/components/ui/collapsible'
|
||||
import {Select, SelectTrigger, SelectValue} from '@/components/ui/select'
|
||||
import products from '@/data/products'
|
||||
import {Link} from '@/i18n/routing'
|
||||
import {getMetaOfFile} from '@/lib/config/resources'
|
||||
import {getProductResources} from '@/lib/data/models/product'
|
||||
import {CategoryPageSqlSchema} from '@/lib/data/models/sqlSchemas'
|
||||
import {db} from '@/lib/db/prisma/client'
|
||||
import {thisLocale, toPrice} from '@/lib/utils'
|
||||
import {dump, thisLocale, toPrice} from '@/lib/utils'
|
||||
import {Button} from '@/ui/button'
|
||||
import {Separator} from '@/ui/separator'
|
||||
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/ui/tabs'
|
||||
|
||||
@@ -35,6 +46,7 @@ export default async function ProductPageIndex({id}: {id: string}) {
|
||||
)
|
||||
|
||||
//const files = await getMetaOfFile(locale.productId)
|
||||
const attrs = products.find(products => products.id === parseInt(id))
|
||||
|
||||
return (
|
||||
<div className='mt-1'>
|
||||
@@ -80,10 +92,21 @@ export default async function ProductPageIndex({id}: {id: string}) {
|
||||
<TabsTrigger value='instuction'>Інструкція</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value='article'>
|
||||
<article
|
||||
className='bw-product__text'
|
||||
dangerouslySetInnerHTML={{__html: locale.content as string}}
|
||||
></article>
|
||||
<div>
|
||||
<h1 className='my-6 ml-12 text-3xl font-bold text-brand-violet'>
|
||||
{locale.headingTitle}
|
||||
</h1>
|
||||
<div
|
||||
className='ml-8 w-[88%] rounded-lg border-x-4 border-brand-violet bg-zinc-50 p-4 leading-relaxed'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: locale.description as string
|
||||
}}
|
||||
></div>
|
||||
<article
|
||||
className='bw-product__text'
|
||||
dangerouslySetInnerHTML={{__html: locale.content as string}}
|
||||
></article>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent value='instuction'>
|
||||
<div
|
||||
@@ -93,13 +116,74 @@ export default async function ProductPageIndex({id}: {id: string}) {
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
<section className='bw-product-col-right bg-gray-50 pt-3'>
|
||||
<section className='bw-product-col-right mt-16 pt-3'>
|
||||
<div className=''>
|
||||
{t('price')}:
|
||||
<span className='ml-2 flex-auto text-right text-xl font-bold text-brand-violet'>
|
||||
{toPrice(locale.price)}
|
||||
</span>
|
||||
</div>
|
||||
{attrs && (
|
||||
<>
|
||||
<Select>
|
||||
<SelectTrigger className='my-4 w-full'>
|
||||
<SelectValue placeholder={attrs?.title} />
|
||||
</SelectTrigger>
|
||||
</Select>
|
||||
<Button className='mb-4 w-full text-brand-violet'>Купити</Button>
|
||||
<div>Є в наявності</div>
|
||||
|
||||
<div className='mb-4 mt-8 font-bold'>Характеристики</div>
|
||||
|
||||
<div className='flex items-center justify-between border-y-2 py-3 pl-1 text-sm'>
|
||||
<div className='text-gray-600'>Категорія</div>
|
||||
<div className='text-brand-violet'>
|
||||
<Link href={`/category/${locale.categorySlug}`}>
|
||||
{locale.categoryTitle}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Collapsible className='border-b-2 py-3 pl-1 text-sm'>
|
||||
<CollapsibleTrigger className='flex w-full items-center justify-between'>
|
||||
<div className='text-gray-600'>Склад</div>
|
||||
<div>
|
||||
<ChevronDown color='#4b5563' />
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className='py-3 text-sm text-gray-600'>
|
||||
Склад 1 капсула містить:
|
||||
<br />
|
||||
сухий екстракт ламінарії (Laminaria japonica Extract 1%
|
||||
iodine) – 15,0 мг (mg), що еквівалентно 150,0 мкг (μg) йоду,
|
||||
<br />
|
||||
селенометіонін ̶ 250,0 мкг (μg), що еквівалентно 100,0 мкг (μg)
|
||||
селену;
|
||||
<br />
|
||||
допоміжні речовини: наповнювач: целюлоза мікрокристалічна,
|
||||
антиспікаючий агент: кремнію діоксид колоїдний безводний,
|
||||
кальцію стеарат.
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
|
||||
<div className='flex items-center justify-between border-b-2 py-3 pl-1 text-sm'>
|
||||
<div className='text-gray-600'>Форма</div>
|
||||
<div className='text-brand-violet'>{attrs?.form}</div>
|
||||
</div>
|
||||
<div className='flex items-center justify-between border-b-2 py-3 pl-1 text-sm'>
|
||||
<div className='text-gray-600'>Виробник</div>
|
||||
<div className='text-brand-violet'>{attrs?.vendor}</div>
|
||||
</div>
|
||||
<div className='flex items-center justify-between border-b-2 py-3 pl-1 text-sm'>
|
||||
<div className='text-gray-600'>Країна-виробник</div>
|
||||
<div className='text-brand-violet'>{attrs?.country}</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className='ml-1 mt-4 inline-block border-b border-dashed border-b-brand-violet pb-2 text-sm text-brand-violet'>
|
||||
Завантажити інструкцію
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function HeaderControls() {
|
||||
const t = useTranslations('cart')
|
||||
|
||||
return (
|
||||
<div className='flex w-full justify-end gap-x-9 text-brand-violet'>
|
||||
<div className='flex w-full justify-end gap-x-6 text-brand-violet'>
|
||||
<CabinetButton />
|
||||
|
||||
<Link href={'#' as never} className='header-button' aria-label='Вибране'>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import {useLocale} from 'next-intl'
|
||||
import {useState} from 'react'
|
||||
|
||||
import {Link} from '@/i18n/routing'
|
||||
@@ -8,7 +9,7 @@ import {Button} from '@/ui/button'
|
||||
|
||||
export default function NavbarMenu() {
|
||||
const bp = 'md'
|
||||
|
||||
const locale = useLocale()
|
||||
const [menuOpened, setMenuOpened] = useState(false)
|
||||
|
||||
function ToggleNavbar() {
|
||||
@@ -19,11 +20,13 @@ export default function NavbarMenu() {
|
||||
<>
|
||||
<div className={`hidden ${bp}:block w-full`}>
|
||||
<div className='flex items-center justify-between'>
|
||||
{data.headerMenus.map(item => (
|
||||
<Link href='/about-us' className='' key={item.name}>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
{data[locale === 'uk' ? 'headerMenus' : 'headerMenusRus'].map(
|
||||
item => (
|
||||
<Link href='/about-us' className='' key={item.name}>
|
||||
{item.name}
|
||||
</Link>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/*<div className={`flex items-center ${bp}:hidden`}>
|
||||
|
||||
Reference in New Issue
Block a user