added tons of features
This commit is contained in:
19
components/shared/above/css/fig-one.module.css
Normal file
19
components/shared/above/css/fig-one.module.css
Normal file
@@ -0,0 +1,19 @@
|
||||
.cls-1 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #f05539;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #b9c2e2;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #a42f23;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #ea5151;
|
||||
}
|
||||
115
components/shared/above/fig-one.tsx
Normal file
115
components/shared/above/fig-one.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import styles from './css/fig-one.module.css'
|
||||
|
||||
const ar = 72.79 / 38.95
|
||||
|
||||
export default function FigOne() {
|
||||
return (
|
||||
<div>
|
||||
<svg
|
||||
id='fig-1'
|
||||
data-name='fig 1'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 72.79 38.95'
|
||||
>
|
||||
<g id='Layer_1' data-name='Layer 1'>
|
||||
<g>
|
||||
<path d='M63.83,21.76c-.23,0-.47-.02-.71-.06-1.25-.2-2.3-.93-3.08-1.54-1.96-1.55-3.6-3.55-4.72-5.79-.06-.11-.01-.25,.1-.31,.11-.06,.25-.01,.31,.1,1.09,2.18,2.68,4.13,4.59,5.64,1.09,.86,1.97,1.31,2.87,1.45,1.07,.17,2.29-.12,3.46-.81,1.07-.63,1.98-1.52,2.87-2.37,.09-.09,.24-.09,.32,0,.09,.09,.09,.24,0,.32-.9,.87-1.84,1.77-2.95,2.43-.75,.44-1.83,.92-3.05,.92Z' />
|
||||
<g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M71.22,16.24c-1.18-.57-2.6-.08-3.17,1.11-.57,1.18-.08,2.6,1.11,3.17,1.18,.57,2.6,.08,3.17-1.11,.57-1.18,.08-2.6-1.11-3.17Z'
|
||||
/>
|
||||
<path d='M70.18,20.99c-.38,0-.77-.08-1.13-.26-1.29-.63-1.84-2.19-1.21-3.48,.3-.63,.83-1.1,1.49-1.33,.66-.23,1.36-.19,1.99,.11,.63,.3,1.1,.83,1.33,1.49,.23,.66,.19,1.36-.11,1.99-.45,.93-1.38,1.47-2.35,1.47Zm0-4.75c-.24,0-.48,.04-.71,.12-.54,.19-.98,.58-1.23,1.09-.52,1.07-.07,2.35,1,2.87,1.07,.52,2.35,.07,2.87-1,.25-.52,.28-1.1,.09-1.64-.19-.54-.58-.98-1.09-1.23h0c-.3-.14-.61-.22-.93-.22Z' />
|
||||
</g>
|
||||
<path d='M6.35,23.78c-1.23,0-2.55-.78-3.91-2.33-.08-.09-.07-.24,.02-.32,.09-.08,.24-.07,.32,.02,1.55,1.76,2.99,2.45,4.27,2.07,1.97-.59,3.5-3.72,4.2-8.6,.02-.13,.13-.21,.26-.19,.12,.02,.21,.13,.19,.26-.73,5.06-2.38,8.33-4.53,8.97-.27,.08-.55,.12-.83,.12Z' />
|
||||
<g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M3.64,19.16c-1.18-.57-2.6-.08-3.17,1.11-.57,1.18-.08,2.6,1.11,3.17,1.18,.57,2.6,.08,3.17-1.11,.57-1.18,.08-2.6-1.11-3.17Z'
|
||||
/>
|
||||
<path d='M2.6,23.91c-.39,0-.77-.09-1.13-.26-.63-.3-1.1-.83-1.33-1.49-.23-.66-.19-1.36,.11-1.99,.62-1.29,2.19-1.84,3.48-1.21h0c.63,.3,1.1,.83,1.33,1.49,.23,.66,.19,1.36-.11,1.99-.3,.63-.83,1.1-1.49,1.33-.28,.1-.57,.15-.86,.15Zm0-4.75c-.8,0-1.57,.45-1.94,1.21-.25,.52-.28,1.1-.09,1.64,.19,.54,.58,.98,1.09,1.23,.52,.25,1.1,.28,1.64,.09,.54-.19,.98-.58,1.23-1.09,.25-.52,.28-1.1,.09-1.64-.19-.54-.58-.98-1.09-1.23h0c-.3-.15-.62-.21-.93-.21Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path d='M28.61,36.94s0,0,0,0c-.13,0-.23-.11-.22-.24,.14-4.32,.09-8.7-.16-13.01,0-.13,.09-.23,.21-.24,.12,0,.23,.09,.24,.21,.25,4.33,.31,8.72,.16,13.05,0,.12-.11,.22-.23,.22Z' />
|
||||
<path d='M28.61,36.94s0,0,0,0c-.13,0-.23-.11-.22-.24,.14-4.32,.09-8.7-.16-13.01,0-.13,.09-.23,.21-.24,.12,0,.23,.09,.24,.21,.25,4.33,.31,8.72,.16,13.05,0,.12-.11,.22-.23,.22Z' />
|
||||
<path d='M42.12,36.94c-.12,0-.22-.1-.23-.22-.14-4.33-.09-8.72,.16-13.05,0-.13,.12-.22,.24-.21,.13,0,.22,.12,.21,.24-.25,4.31-.31,8.69-.16,13.01,0,.13-.09,.23-.22,.24,0,0,0,0,0,0Z' />
|
||||
<g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M26.88,35.49c-.94,.1-1.94,.22-2.59,1-.32,.39-.44,.93-.24,1.39,.31,.72,1.12,.82,1.83,.83,1.07,.02,2.07,.02,3.12-.21,.64-.14,1.02-.52,1.09-2,.02-.53-.39-.99-.93-1.01-.78-.03-1.83-.06-2.29,0Z'
|
||||
/>
|
||||
<path d='M26.6,38.95c-.24,0-.48,0-.72,0-.81-.02-1.68-.14-2.04-.97-.23-.52-.12-1.15,.27-1.63,.72-.87,1.84-.99,2.74-1.09h0c.47-.05,1.52-.02,2.32,0,.32,.01,.62,.15,.83,.39,.22,.24,.33,.54,.31,.86-.06,1.43-.41,2.03-1.27,2.22-.84,.18-1.64,.22-2.45,.22Zm.3-3.24c-.86,.09-1.83,.19-2.43,.92-.29,.35-.36,.79-.21,1.16,.25,.59,.93,.68,1.63,.69,1.02,.02,2.03,.02,3.07-.21,.46-.1,.84-.3,.91-1.79,0-.2-.06-.38-.19-.53-.13-.15-.32-.23-.51-.24-1.11-.04-1.91-.05-2.25,0h0Zm-.02-.23h0Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M43.85,35.49c.94,.1,1.94,.22,2.59,1,.32,.39,.44,.93,.24,1.39-.31,.72-1.12,.82-1.83,.83-1.07,.02-2.07,.02-3.12-.21-.64-.14-1.02-.52-1.09-2-.02-.53,.39-.99,.93-1.01,.78-.03,1.83-.06,2.29,0Z'
|
||||
/>
|
||||
<path d='M44.12,38.95c-.81,0-1.61-.04-2.45-.22-.86-.19-1.2-.79-1.27-2.22-.01-.32,.1-.62,.31-.86,.22-.24,.51-.37,.83-.39,.8-.03,1.85-.06,2.32,0h0c.9,.09,2.02,.21,2.74,1.09,.39,.48,.5,1.1,.27,1.63-.36,.83-1.23,.95-2.04,.97-.24,0-.48,0-.72,0Zm-1.05-3.26c-.4,0-.91,.01-1.5,.03-.2,0-.38,.09-.51,.24-.13,.15-.2,.33-.19,.53,.07,1.49,.45,1.69,.91,1.79,1.04,.23,2.04,.23,3.07,.21,.7-.01,1.37-.11,1.63-.69,.16-.37,.08-.81-.21-1.16-.6-.73-1.57-.83-2.43-.92h0c-.16-.02-.41-.03-.75-.03Z' />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path d='M58.22,11.86c-.12-1.22-.31-2.86-.87-3.96-.88-1.74-2.08-2.55-3.92-3.21-1.84-.67-4.34-.86-6.28-1.05-2.7-.26-9.2-.48-12.34-.48s-9.64,.22-12.34,.48c-1.95,.19-4.44,.39-6.28,1.05-1.84,.67-3.03,1.47-3.92,3.21-.56,1.1-.75,2.74-.87,3.96-.12,1.22-.16,2.45-.13,3.67-.03,1.22,.01,2.45,.13,3.67,.12,1.22,.31,2.86,.87,3.96,.88,1.74,2.08,2.55,3.92,3.21,1.84,.67,4.34,.86,6.28,1.05,2.7,.26,8.18,.48,12.34,.48s9.64-.22,12.34-.48c1.95-.19,4.44-.39,6.28-1.05,1.84-.67,3.03-1.47,3.92-3.21,.56-1.1,.75-2.73,.87-3.96,.12-1.22,.16-2.45,.13-3.67,.03-1.22-.01-2.45-.13-3.67Z' />
|
||||
<path d='M34.81,28.15c-4.1,0-9.65-.22-12.36-.48l-.49-.05c-1.84-.18-4.14-.4-5.85-1.02-2.4-.87-3.35-1.96-4.05-3.33-.55-1.09-.76-2.66-.9-4.05-.12-1.21-.16-2.45-.13-3.7-.03-1.24,.02-2.48,.13-3.69,.13-1.39,.34-2.96,.9-4.05,.96-1.9,2.32-2.7,4.05-3.33,1.72-.62,4.01-.84,5.85-1.02l.49-.05c2.6-.25,9.08-.48,12.36-.48s9.76,.23,12.36,.48l.49,.05c1.84,.18,4.14,.4,5.85,1.02,2.4,.87,3.35,1.96,4.05,3.33,.55,1.09,.76,2.66,.9,4.05,.12,1.21,.16,2.45,.13,3.7,.03,1.24-.02,2.48-.13,3.69-.13,1.39-.34,2.96-.9,4.05-.96,1.9-2.32,2.7-4.05,3.33-1.72,.62-4.01,.84-5.85,1.02l-.49,.05c-2.71,.27-8.26,.48-12.36,.48Zm0-24.75c-3.27,0-9.72,.23-12.32,.48l-.49,.05c-1.82,.17-4.08,.39-5.73,.99-1.67,.61-2.89,1.34-3.78,3.1-.52,1.02-.72,2.53-.84,3.87-.11,1.19-.16,2.41-.13,3.64-.03,1.24,.02,2.46,.13,3.65,.13,1.34,.33,2.86,.84,3.87,.89,1.76,2.11,2.49,3.78,3.1,1.66,.6,3.92,.82,5.73,.99l.49,.05c2.7,.26,8.23,.48,12.32,.48s9.61-.21,12.32-.48l.49-.05c1.82-.17,4.08-.39,5.73-.99,1.67-.61,2.89-1.34,3.78-3.1,.52-1.02,.72-2.53,.84-3.87,.11-1.19,.16-2.41,.13-3.64,.03-1.24-.02-2.46-.13-3.65h0c-.13-1.34-.33-2.86-.84-3.87-.89-1.76-2.11-2.49-3.78-3.1-1.66-.6-3.92-.82-5.73-.99l-.49-.05c-2.59-.25-9.05-.48-12.32-.48Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
className='cls-3'
|
||||
d='M58.22,8.95c-.12-1.22-.31-2.86-.87-3.96-.88-1.74-2.08-2.55-3.92-3.21-1.84-.67-4.34-.86-6.28-1.05-2.7-.26-9.2-.48-12.34-.48s-9.64,.22-12.34,.48c-1.95,.19-4.44,.39-6.28,1.05-1.84,.67-3.03,1.47-3.92,3.21-.56,1.1-.75,2.74-.87,3.96-.12,1.22-.16,2.45-.13,3.67-.03,1.22,.01,2.45,.13,3.67,.12,1.22,.31,2.86,.87,3.96,.88,1.74,2.08,2.55,3.92,3.21,1.84,.67,4.34,.86,6.28,1.05,2.7,.26,8.18,.48,12.34,.48s9.64-.22,12.34-.48c1.95-.19,4.44-.39,6.28-1.05,1.84-.67,3.03-1.47,3.92-3.21,.56-1.1,.75-2.74,.87-3.96,.12-1.22,.16-2.45,.13-3.67,.03-1.22-.01-2.45-.13-3.67Z'
|
||||
/>
|
||||
<path d='M34.81,25.25c-4.1,0-9.65-.22-12.36-.48l-.49-.05c-1.84-.18-4.14-.4-5.85-1.02-2.4-.87-3.35-1.96-4.05-3.33-.55-1.09-.76-2.66-.9-4.05-.12-1.21-.16-2.45-.13-3.7-.03-1.24,.02-2.48,.13-3.69,.13-1.39,.34-2.96,.9-4.05,.96-1.9,2.32-2.7,4.05-3.33,1.72-.62,4.01-.84,5.85-1.02l.49-.05c2.6-.25,9.08-.48,12.36-.48s9.76,.23,12.36,.48l.49,.05c1.84,.18,4.14,.4,5.85,1.02,2.4,.87,3.35,1.96,4.05,3.33,.55,1.09,.76,2.66,.9,4.05,.12,1.21,.16,2.45,.13,3.7,.03,1.24-.02,2.48-.13,3.69-.13,1.39-.34,2.96-.9,4.05-.96,1.9-2.32,2.7-4.05,3.33-1.72,.62-4.01,.84-5.86,1.02l-.49,.05c-2.71,.27-8.26,.48-12.36,.48ZM34.81,.49c-3.27,0-9.72,.23-12.32,.48l-.49,.05c-1.82,.17-4.07,.39-5.73,.99-1.67,.61-2.89,1.34-3.78,3.1-.52,1.02-.72,2.53-.84,3.87-.11,1.19-.16,2.41-.13,3.64-.03,1.24,.02,2.46,.13,3.65,.13,1.34,.33,2.86,.84,3.87,.89,1.76,2.11,2.49,3.78,3.1,1.66,.6,3.92,.82,5.73,.99l.49,.05c2.7,.26,8.23,.48,12.32,.48s9.61-.21,12.32-.48l.49-.05c1.82-.17,4.08-.39,5.73-.99,1.67-.61,2.89-1.34,3.78-3.1,.52-1.02,.72-2.53,.84-3.87,.11-1.19,.16-2.41,.13-3.64,.03-1.24-.02-2.46-.13-3.65h0c-.13-1.34-.33-2.86-.84-3.87-.89-1.76-2.11-2.49-3.78-3.1-1.66-.6-3.92-.82-5.73-.99l-.49-.05c-2.59-.25-9.05-.48-12.32-.48Z' />
|
||||
</g>
|
||||
<path d='M34.81,25.25c-.14,0-.25-.11-.25-.25V.25c0-.14,.11-.25,.25-.25s.25,.11,.25,.25V25c0,.14-.11,.25-.25,.25Z' />
|
||||
<g>
|
||||
<path
|
||||
className='cls-4'
|
||||
d='M30.17,12.96c-1.08,0-1.65,1.28-.91,2.07,.5,.54,1.05,1.04,1.66,1.49,1.34,.99,3.05,1.59,4.7,1.3,1.11-.2,2.12-.8,3.02-1.47,.51-.38,.99-.79,1.45-1.23,.81-.77,.26-2.13-.85-2.13-2.69,.01-6.52-.01-9.07-.03Z'
|
||||
/>
|
||||
<path d='M34.76,18.12c-1.32,0-2.73-.49-3.98-1.42-.6-.45-1.16-.94-1.7-1.52-.4-.43-.51-1.04-.27-1.58,.24-.55,.75-.88,1.35-.88h0c3.24,.02,6.59,.04,9.07,.03h0c.61,0,1.13,.35,1.35,.92,.23,.57,.1,1.18-.35,1.61-.47,.44-.96,.86-1.47,1.25-1.14,.85-2.13,1.34-3.12,1.52-.29,.05-.59,.08-.9,.08Zm-4.6-4.93c-.48,0-.79,.31-.92,.6-.13,.29-.15,.73,.18,1.08,.52,.55,1.05,1.03,1.63,1.46,1.43,1.06,3.08,1.52,4.52,1.25,.92-.17,1.85-.62,2.93-1.43,.5-.37,.98-.78,1.43-1.21,.36-.35,.36-.8,.24-1.1-.12-.3-.43-.63-.93-.63h0c-2.49,.01-5.83,0-9.07-.03h0Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
className='cls-5'
|
||||
d='M36.02,16.31c-.64-.17-1.31-.24-1.97-.2-.66,.04-1.32,.2-1.92,.47-.21,.1-.42,.21-.61,.33,1.24,.75,2.7,1.16,4.11,.91,.71-.13,1.38-.42,2.01-.79-.5-.33-1.04-.57-1.61-.72Z'
|
||||
/>
|
||||
<path d='M34.76,18.12c-1.11,0-2.28-.35-3.37-1.01-.07-.04-.11-.11-.11-.19,0-.08,.04-.15,.11-.2,.21-.13,.42-.25,.64-.35,.62-.28,1.29-.45,2-.49,.69-.05,1.38,.02,2.05,.21h0c.6,.16,1.17,.42,1.68,.75,.07,.04,.11,.12,.1,.2,0,.08-.04,.15-.11,.19-.72,.43-1.41,.69-2.08,.82-.29,.05-.59,.08-.9,.08Zm-2.8-1.21c1.2,.65,2.47,.89,3.62,.68,.52-.09,1.04-.28,1.6-.57-.38-.21-.79-.38-1.22-.49h0c-.62-.17-1.26-.23-1.9-.19-.66,.04-1.28,.2-1.84,.45-.08,.04-.17,.08-.25,.12Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M30.76,14.09c.33,.14,2.82,.36,3.93,.36,.7,0,3.37-.09,3.97-.25,.32-.08,1.11-.83,1.2-1.04-.18-.1-.38-.16-.61-.16-2.69,.01-6.52-.01-9.07-.03-.12,0-.24,.02-.35,.05,.05,.16,.64,.95,.94,1.08Z'
|
||||
/>
|
||||
<path d='M34.66,14.67c-1.06,0-3.6-.2-3.99-.37h0c-.38-.17-1-1.01-1.07-1.22-.02-.06-.01-.12,.02-.18s.08-.09,.14-.11c.13-.04,.28-.05,.41-.06,3.24,.02,6.59,.04,9.07,.03,.26,0,.51,.06,.73,.19,.1,.06,.14,.18,.1,.28-.11,.27-.96,1.08-1.35,1.18-.64,.17-3.39,.26-4.03,.26-.01,0-.02,0-.03,0Zm-4.46-1.48c.19,.26,.5,.62,.65,.68h0c.26,.11,2.67,.34,3.84,.34,.73,0,3.36-.1,3.91-.24,.18-.05,.65-.46,.9-.72-.08-.02-.17-.03-.25-.03-2.48,.01-5.81,0-9.05-.03Z' />
|
||||
</g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M55.06,10.09c-.39,0-.75-.25-.87-.64-.6-1.93-2.15-3.59-4.03-4.33-.47-.18-.7-.72-.52-1.19,.18-.47,.71-.7,1.19-.52,2.43,.95,4.34,3,5.11,5.49,.15,.48-.12,1-.6,1.15-.09,.03-.18,.04-.27,.04Z'
|
||||
/>
|
||||
<g>
|
||||
<path d='M40.98,10.04c0-1.04,.53-1.56,1.18-1.56s1.18,.52,1.18,1.56-.53,1.56-1.18,1.56-1.18-.52-1.18-1.56' />
|
||||
<path d='M26.28,10.04c0-1.04,.53-1.56,1.18-1.56s1.18,.52,1.18,1.56-.53,1.56-1.18,1.56-1.18-.52-1.18-1.56' />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
className='cls-2'
|
||||
d='M24.91,13.48c0,1.16-.94,2.11-2.11,2.11s-2.11-.94-2.11-2.11,.94-2.11,2.11-2.11,2.11,.94,2.11,2.11Z'
|
||||
/>
|
||||
<path
|
||||
className='cls-2'
|
||||
d='M48.92,13.48c0,1.16-.94,2.11-2.11,2.11s-2.11-.94-2.11-2.11,.94-2.11,2.11-2.11,2.11,.94,2.11,2.11Z'
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M15.38,20.59c-.33,0-.65-.18-.81-.49-.48-.92-.78-1.96-.85-2.99-.04-.5,.34-.94,.85-.98,.5-.04,.94,.34,.98,.85,.06,.79,.28,1.58,.65,2.28,.23,.45,.06,1-.39,1.23-.14,.07-.28,.1-.42,.1Z'
|
||||
/>
|
||||
<path
|
||||
className='cls-1'
|
||||
d='M18.01,22.51c-.14,0-.28-.03-.41-.1l-.48-.24c-.45-.23-.64-.78-.41-1.23,.23-.45,.78-.64,1.23-.41l.48,.24c.45,.23,.64,.78,.41,1.23-.16,.32-.48,.51-.82,.51Z'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
3
components/shared/above/fig-three.tsx
Normal file
3
components/shared/above/fig-three.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function FigThree() {
|
||||
return <></>
|
||||
}
|
||||
3
components/shared/above/fig-two.tsx
Normal file
3
components/shared/above/fig-two.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function FigTwo() {
|
||||
return <div>Fig1</div>
|
||||
}
|
||||
47
components/shared/above/index.tsx
Normal file
47
components/shared/above/index.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
'use client'
|
||||
|
||||
import {useTranslations} from 'next-intl'
|
||||
import Image from 'next/image'
|
||||
|
||||
import Fig1 from '@/public/images/above/fig-1.svg'
|
||||
import Fig2 from '@/public/images/above/fig-2.svg'
|
||||
import Fig3 from '@/public/images/above/fig-3.svg'
|
||||
|
||||
export default function Above() {
|
||||
const t = useTranslations('Banner.Above')
|
||||
|
||||
return (
|
||||
<div className='flex w-full items-end justify-center bg-brand-violet md:min-h-[43px] xl:min-h-[51px]'>
|
||||
<div className='mx-0 mb-0.5'>
|
||||
<Image
|
||||
width={72.79}
|
||||
height={38.95}
|
||||
src={Fig1}
|
||||
alt=''
|
||||
className='max-h-[35px]'
|
||||
/>
|
||||
</div>
|
||||
<div className='mx-0'>
|
||||
<Image
|
||||
width={80.21}
|
||||
height={43.78}
|
||||
src={Fig2}
|
||||
alt=''
|
||||
className='max-h-[41px]'
|
||||
/>
|
||||
</div>
|
||||
<div className='self-center font-medium text-brand-yellow'>
|
||||
{t('title')}
|
||||
</div>
|
||||
<div className='mx-1'>
|
||||
<Image
|
||||
width={98.89}
|
||||
height={47.27}
|
||||
src={Fig3}
|
||||
alt=''
|
||||
className='max-h-[37px]'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
175
components/shared/app-sidebar.tsx~
Normal file
175
components/shared/app-sidebar.tsx~
Normal file
@@ -0,0 +1,175 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
AudioWaveform,
|
||||
BookOpen,
|
||||
Bot,
|
||||
Command,
|
||||
Frame,
|
||||
GalleryVerticalEnd,
|
||||
Map,
|
||||
PieChart,
|
||||
Settings2,
|
||||
SquareTerminal
|
||||
} from 'lucide-react'
|
||||
import * as React from 'react'
|
||||
|
||||
import {NavMain} from '@/components/shared/nav-main'
|
||||
import {NavProjects} from '@/components/shared/nav-projects'
|
||||
import {NavUser} from '@/components/shared/nav-user'
|
||||
import {TeamSwitcher} from '@/components/shared/team-switcher'
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarHeader,
|
||||
SidebarRail
|
||||
} from '@/components/ui/sidebar'
|
||||
|
||||
// This is sample data.
|
||||
const data = {
|
||||
user: {
|
||||
name: 'shadcn',
|
||||
email: 'm@example.com',
|
||||
avatar: '/avatars/shadcn.jpg'
|
||||
},
|
||||
teams: [
|
||||
{
|
||||
name: 'Acme Inc',
|
||||
logo: GalleryVerticalEnd,
|
||||
plan: 'Enterprise'
|
||||
},
|
||||
{
|
||||
name: 'Acme Corp.',
|
||||
logo: AudioWaveform,
|
||||
plan: 'Startup'
|
||||
},
|
||||
{
|
||||
name: 'Evil Corp.',
|
||||
logo: Command,
|
||||
plan: 'Free'
|
||||
}
|
||||
],
|
||||
navMain: [
|
||||
{
|
||||
title: 'Playground',
|
||||
url: '#',
|
||||
icon: SquareTerminal,
|
||||
isActive: true,
|
||||
items: [
|
||||
{
|
||||
title: 'History',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Starred',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
url: '#'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Models',
|
||||
url: '#',
|
||||
icon: Bot,
|
||||
items: [
|
||||
{
|
||||
title: 'Genesis',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Explorer',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Quantum',
|
||||
url: '#'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Documentation',
|
||||
url: '#',
|
||||
icon: BookOpen,
|
||||
items: [
|
||||
{
|
||||
title: 'Introduction',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Get Started',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Tutorials',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Changelog',
|
||||
url: '#'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
url: '#',
|
||||
icon: Settings2,
|
||||
items: [
|
||||
{
|
||||
title: 'General',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Team',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Billing',
|
||||
url: '#'
|
||||
},
|
||||
{
|
||||
title: 'Limits',
|
||||
url: '#'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
projects: [
|
||||
{
|
||||
name: 'Design Engineering',
|
||||
url: '#',
|
||||
icon: Frame
|
||||
},
|
||||
{
|
||||
name: 'Sales & Marketing',
|
||||
url: '#',
|
||||
icon: PieChart
|
||||
},
|
||||
{
|
||||
name: 'Travel',
|
||||
url: '#',
|
||||
icon: Map
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export function AppSidebar({...props}: React.ComponentProps<typeof Sidebar>) {
|
||||
return (
|
||||
<Sidebar {...props}>
|
||||
<SidebarHeader>
|
||||
<TeamSwitcher teams={data.teams} />
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<NavMain items={data.navMain} />
|
||||
<NavProjects projects={data.projects} />
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavUser user={data.user} />
|
||||
</SidebarFooter>
|
||||
<SidebarRail />
|
||||
</Sidebar>
|
||||
)
|
||||
}
|
||||
56
components/shared/editor/jodit.tsx
Normal file
56
components/shared/editor/jodit.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
'use client'
|
||||
|
||||
// https://xdsoft.net/jodit/play.html?spellcheck=true&language=ua&direction=ltr&saveHeightInStorage=true&saveModeInStorage=true&defaultActionOnPaste=insert_as_text&disablePlugins=ai-assistant%2Cmobile%2Cprint%2Cspeech-recognize%2Ctable%2Ctable-keyboard-navigation%2Cpowered-by-jodit%2Ciframe&minHeight=360&maxHeight=NaN&maxWidth=NaN&buttons=bold%2Citalic%2Cunderline%2Cstrikethrough%2Ceraser%2Cul%2Col%2Cfont%2Cfontsize%2Cparagraph%2ClineHeight%2Csuperscript%2Csubscript%2CclassSpan%2Cfile%2Cimage%2Cvideo%2Cspellcheck%2Ccut
|
||||
//import JoditEditor from 'jodit-react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import React, {useMemo, useRef, useState} from 'react'
|
||||
|
||||
const JoditEditor = dynamic(() => import('jodit-react'), {ssr: false})
|
||||
|
||||
export default function BasicEditor({
|
||||
placeholder,
|
||||
maxHeight,
|
||||
handleChange
|
||||
}: {
|
||||
placeholder: string
|
||||
maxHeight: number
|
||||
handleChange: any
|
||||
}) {
|
||||
const editor = useRef(null)
|
||||
const [content, setContent] = useState('')
|
||||
|
||||
const config = useMemo(
|
||||
() => ({
|
||||
readonly: false, // all options from https://xdsoft.net/jodit/docs/,
|
||||
placeholder: placeholder || 'Start typings...',
|
||||
spellcheck: true,
|
||||
language: 'ua',
|
||||
saveHeightInStorage: true,
|
||||
saveModeInStorage: true,
|
||||
//defaultActionOnPaste: 'insert_as_text',
|
||||
disablePlugins:
|
||||
'ai-assistant,mobile,print,speech-recognize,table,table-keyboard-navigation,powered-by-jodit,iframe',
|
||||
minHeight: maxHeight || 320,
|
||||
maxHeight: 1100,
|
||||
// maxWidth: 992,
|
||||
uploader: {
|
||||
insertImageAsBase64URI: true,
|
||||
imagesExtensions: ['jpg', 'png', 'jpeg', 'gif', 'svg', 'webp']
|
||||
},
|
||||
buttons:
|
||||
'bold,italic,underline,strikethrough,eraser,ul,ol,font,fontsize,paragraph,lineHeight,superscript,subscript,classSpan,file,image,video,spellcheck,cut'
|
||||
}),
|
||||
[placeholder, maxHeight]
|
||||
)
|
||||
|
||||
return (
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={content}
|
||||
config={config}
|
||||
tabIndex={1} // tabIndex of textarea
|
||||
onBlur={newContent => setContent(newContent)} // preferred to use only this option to update the content for performance reasons
|
||||
onChange={handleChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
28
components/shared/footer.tsx
Normal file
28
components/shared/footer.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
'use client'
|
||||
|
||||
// 31:47
|
||||
import {ChevronUp} from 'lucide-react'
|
||||
|
||||
import SocialMediaPanel from '@/components/shared/social-media-panel'
|
||||
import {Button} from '@/ui/button'
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className='bg-brand-violet w-full py-3 text-white'>
|
||||
<div className='container flex items-center justify-between'>
|
||||
<div>Політика конфіденційності</div>
|
||||
<div>Договір оферти</div>
|
||||
<div>Доставка і повернення</div>
|
||||
<div>Контакти</div>
|
||||
<SocialMediaPanel color='#fff' />
|
||||
<Button
|
||||
variant='ghost'
|
||||
className='bg-brand-violet rounded-none'
|
||||
onClick={() => window.scrollTo({top: 0, behavior: 'smooth'})}
|
||||
>
|
||||
<ChevronUp className='mr-2 h-4 w-4' />
|
||||
</Button>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
33
components/shared/header/cabinet-button.tsx
Normal file
33
components/shared/header/cabinet-button.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import {CircleUserRound} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
|
||||
import {auth} from '@/auth'
|
||||
import {avatarFallback} from '@/lib/utils'
|
||||
import {Avatar, AvatarFallback, AvatarImage} from '@/ui/avatar'
|
||||
|
||||
export default async function CabinetButton() {
|
||||
const session = await auth()
|
||||
|
||||
return (
|
||||
<Link href='/cabinet' className='header-button' aria-label='Кабінет'>
|
||||
<button className='flex flex-col items-center' role='button'>
|
||||
{session ? (
|
||||
<>
|
||||
<Avatar className='hs1-[21px] w1-[21px] border2-2 border2-brand-violet'>
|
||||
<AvatarImage src={session.user?.image as string} alt='avatar' />
|
||||
<AvatarFallback className='text-xs'>
|
||||
{avatarFallback(session.user?.name as string)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CircleUserRound className='h-[21px] w-[21px]' />
|
||||
GA4_Ecommerce_View_Item_List_Trigger
|
||||
</>
|
||||
)}
|
||||
{/*<span className='text-sm'>Кабінет</span>*/}
|
||||
</button>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
34
components/shared/header/controls.tsx
Normal file
34
components/shared/header/controls.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import {Heart, ShoppingCartIcon, UserIcon} from 'lucide-react'
|
||||
import {useTranslations} from 'next-intl'
|
||||
|
||||
import CabinetButton from '@/components/shared/header/cabinet-button'
|
||||
import {Link} from '@/i18n/routing'
|
||||
|
||||
export default function HeaderControls() {
|
||||
const t = useTranslations('cart')
|
||||
|
||||
return (
|
||||
<div className='flex w-full justify-end gap-x-9 text-brand-violet'>
|
||||
<CabinetButton />
|
||||
|
||||
<Link href={'#' as never} className='header-button' aria-label='Вибране'>
|
||||
<button className='flex flex-col items-center' role='button'>
|
||||
<Heart className='h-[21px] w-[21px]' />
|
||||
<span className='font1-bold text-sm'>{t('favorites')}</span>
|
||||
</button>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/checkout' as never}
|
||||
className='header-button'
|
||||
aria-label='Кошик'
|
||||
>
|
||||
<button className='flex flex-col items-center' role='button'>
|
||||
<ShoppingCartIcon className='h-[21px] w-[21px]' />
|
||||
|
||||
<span className='font1-bold text-sm'>{t('basket')}</span>
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
54
components/shared/header/index.tsx
Normal file
54
components/shared/header/index.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import {Menu} from '@radix-ui/react-menu'
|
||||
|
||||
import HeaderControls from './controls'
|
||||
import Logo from '@/components/shared/home/logo'
|
||||
import LocaleSwitcher from '@/components/shared/locale-switcher'
|
||||
import Navbar from '@/components/shared/navbar'
|
||||
import SearchForm from '@/components/shared/search/form'
|
||||
import SocialMediaPanel from '@/components/shared/social-media-panel'
|
||||
import {Switch} from '@/ui/switch'
|
||||
|
||||
type MenuProps = {
|
||||
name: string
|
||||
slug: string
|
||||
href: string
|
||||
}
|
||||
|
||||
export default async function Header() {
|
||||
/*{
|
||||
searchParams
|
||||
}: {
|
||||
searchParams: Promise<{query?: string}>
|
||||
}*/
|
||||
//const query = (await searchParams).query
|
||||
|
||||
return (
|
||||
<header className='w-full border-none bg-background text-white'>
|
||||
<div className='container flex'>
|
||||
<div className='bw-layout-col-left'>
|
||||
<Logo />
|
||||
</div>
|
||||
<div className='bw-layout-col-right flex-col'>
|
||||
<div className='mt-1.5 flex h-10 items-center'>
|
||||
<div className='bw-header-col-left flex justify-between gap-x-10'>
|
||||
<Navbar />
|
||||
<SocialMediaPanel size={16} className='gap-x-3 pr-1' />
|
||||
</div>
|
||||
<div className='bw-header-col-right flex justify-end text-stone'>
|
||||
<LocaleSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='flex items-center'>
|
||||
<div className='bw-header-col-left'>
|
||||
<SearchForm />
|
||||
</div>
|
||||
<div className='bw-header-col-right'>
|
||||
<HeaderControls />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
44
components/shared/home/feature-cards.tsx
Normal file
44
components/shared/home/feature-cards.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import Image from 'next/image'
|
||||
import * as React from 'react'
|
||||
|
||||
import {cards} from '@/lib/data'
|
||||
import {Card, CardContent} from '@/ui/card'
|
||||
import {Carousel, CarouselContent, CarouselItem} from '@/ui/carousel'
|
||||
|
||||
export default function FeatureCards() {
|
||||
return (
|
||||
<Carousel className='mx-auto w-full'>
|
||||
<CarouselContent className='-ml-2 md:-ml-4'>
|
||||
{cards.map((card: any) => (
|
||||
<CarouselItem
|
||||
key={card.title}
|
||||
className='pl-3 md:basis-1/3 lg:basis-1/4 xl:basis-1/5'
|
||||
>
|
||||
<div className='p-1'>
|
||||
<Card className='border-[2px] border-brand-violet'>
|
||||
<CardContent className='aspect-card flex items-center justify-center p-1'>
|
||||
<CarouselItem>
|
||||
<Image
|
||||
src={card.image}
|
||||
width={256}
|
||||
height={256}
|
||||
className='object-scale-down'
|
||||
priority
|
||||
alt={''}
|
||||
/>
|
||||
</CarouselItem>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
|
||||
/*<div className='container grid grid-cols-1 md:grid-cols-2 md:gap-44 lg:grid-cols-4'>
|
||||
{cards.map((card: any) => (
|
||||
<ProductCard card={card} key={card.title} />
|
||||
))}
|
||||
</div>*/
|
||||
)
|
||||
}
|
||||
74
components/shared/home/home-carousel.tsx
Normal file
74
components/shared/home/home-carousel.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
'use client'
|
||||
|
||||
import Autoplay from 'embla-carousel-autoplay'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import * as React from 'react'
|
||||
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious
|
||||
} from '@/components/ui/carousel'
|
||||
import {cn} from '@/lib/utils'
|
||||
|
||||
export function HomeCarousel({
|
||||
items
|
||||
}: {
|
||||
items: {
|
||||
image: string
|
||||
url: string
|
||||
title: string
|
||||
buttonCaption: string
|
||||
}[]
|
||||
}) {
|
||||
const plugin = React.useRef(Autoplay({delay: 5000, stopOnInteraction: true}))
|
||||
|
||||
return (
|
||||
<Carousel
|
||||
dir='ltr'
|
||||
plugins={[plugin.current]}
|
||||
className='mx-auto w-full'
|
||||
onMouseEnter={plugin.current.stop}
|
||||
onMouseLeave={plugin.current.reset}
|
||||
>
|
||||
<CarouselContent>
|
||||
{items.map(item => (
|
||||
<CarouselItem key={item.title}>
|
||||
<Link href={item.url}>
|
||||
<div className='relative -m-0.5 flex aspect-univisium items-center justify-center'>
|
||||
<Image
|
||||
src={item.image}
|
||||
alt={item.title}
|
||||
fill
|
||||
className='object-cover'
|
||||
priority
|
||||
/>
|
||||
<div className='absolute left-16 top-1/2 hidden w-1/3 -translate-y-1/2 transform md:left-32'>
|
||||
<h2
|
||||
className={cn(
|
||||
'mb-4 text-lg font-bold text-primary shadow-brand-violet drop-shadow-xl md:text-6xl'
|
||||
)}
|
||||
>
|
||||
{`${item.title}`}
|
||||
</h2>
|
||||
<Button className='hidden md:block'>
|
||||
{`${item.buttonCaption}`}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
{/*<CarouselPrevious className='left-0 h-[78px] w-[78px] text-6xl md:left-12' />
|
||||
<CarouselNext className='right-0 h-[78px] w-[78px] md:right-12' />*/}
|
||||
|
||||
<CarouselPrevious className='absolute left-[1rem] top-1/2 z-10 h-[78px] w-[78px] -translate-y-1/2 transform' />
|
||||
<CarouselNext className='absolute right-[1rem] top-1/2 z-10 h-[78px] w-[78px] -translate-y-1/2 transform' />
|
||||
</Carousel>
|
||||
)
|
||||
}
|
||||
29
components/shared/home/logo.tsx
Normal file
29
components/shared/home/logo.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
|
||||
import {APP_NAME} from '@/lib/constants'
|
||||
import logoImg from '@/public/images/logo.svg'
|
||||
|
||||
export default function Logo() {
|
||||
const ar = 121 / 192
|
||||
const w = 112
|
||||
|
||||
return (
|
||||
<div className='mt-0.5 flex items-center justify-center'>
|
||||
<Link
|
||||
href='/'
|
||||
className='m-1 flex cursor-pointer items-center pt-[7px] text-2xl font-extrabold outline-0'
|
||||
>
|
||||
<Image
|
||||
src={logoImg}
|
||||
width={w}
|
||||
height={w * ar}
|
||||
alt={`${APP_NAME} logo`}
|
||||
className='w-[131]'
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
34
components/shared/icons/google.tsx
Normal file
34
components/shared/icons/google.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
|
||||
import IconProps from '@/components/shared/icons/props'
|
||||
import {cn} from '@/lib/utils'
|
||||
|
||||
export default function GoogleIcon({className, size, color}: IconProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size || 24}
|
||||
height={size || 24}
|
||||
viewBox='0 0 24 24'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
className={cn('bw-icon', className)}
|
||||
>
|
||||
<path
|
||||
d='M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z'
|
||||
fill='#4285F4'
|
||||
/>
|
||||
<path
|
||||
d='M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z'
|
||||
fill='#34A853'
|
||||
/>
|
||||
<path
|
||||
d='M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z'
|
||||
fill='#FBBC05'
|
||||
/>
|
||||
<path
|
||||
d='M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z'
|
||||
fill='#EA4335'
|
||||
/>
|
||||
<path d='M1 1h22v22H1z' fill='none' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
5
components/shared/icons/props.ts
Normal file
5
components/shared/icons/props.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default interface IconProps {
|
||||
className?: string
|
||||
size?: string | number
|
||||
color?: string
|
||||
}
|
||||
22
components/shared/icons/whatsapp.tsx
Normal file
22
components/shared/icons/whatsapp.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import IconProps from '@/components/shared/icons/props'
|
||||
import {BRAND_ICON_COLOR} from '@/lib/constants'
|
||||
import {cn} from '@/lib/utils'
|
||||
|
||||
export default function WhatsappIcon({className, size, color}: IconProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size || 24}
|
||||
height={size || 24}
|
||||
viewBox='0 0 24 24'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
{/*https://lineicons.com/icons?q=goo*/}
|
||||
<path
|
||||
className={cn('bw-icon', className)}
|
||||
d='M19.074 4.89389C17.2091 3.02894 14.6689 2 12.0644 2C6.59814 2 2.12869 6.4373 2.12869 11.9035C2.12869 13.672 2.57885 15.3441 3.44702 16.8875L2.03223 22L7.33769 20.6495C8.78464 21.4212 10.4245 21.8714 12.0965 21.8714C17.5306 21.8392 21.9679 17.4019 21.9679 11.9035C21.9679 9.26688 20.939 6.791 19.074 4.89389ZM12.0322 20.1672C10.5853 20.1672 9.07403 19.7492 7.82001 18.9775L7.49846 18.7846L4.37949 19.5884L5.24766 16.5659L5.05473 16.2444C4.25088 14.926 3.80072 13.3826 3.80072 11.8392C3.80072 7.30547 7.46631 3.63987 12.0322 3.63987C14.2187 3.63987 16.2766 4.50804 17.82 6.05145C19.3634 7.59486 20.2316 9.68489 20.2316 11.9035C20.2959 16.5016 16.566 20.1672 12.0322 20.1672ZM16.566 13.9936C16.3088 13.865 15.119 13.254 14.8297 13.2219C14.6046 13.1254 14.4116 13.0932 14.283 13.3505C14.1544 13.6077 13.6399 14.1222 13.5113 14.3151C13.3827 14.4437 13.2541 14.508 12.9647 14.3473C12.7075 14.2187 11.9358 13.9936 10.9711 13.0932C10.2316 12.4502 9.71711 11.6463 9.62065 11.3569C9.49203 11.0997 9.5885 11.0032 9.74927 10.8424C9.87788 10.7138 10.0065 10.5852 10.103 10.3923C10.2316 10.2637 10.2316 10.135 10.3602 9.97428C10.4888 9.84566 10.3924 9.65274 10.328 9.52412C10.2316 9.3955 9.78142 8.17364 9.55634 7.65917C9.36342 7.1447 9.13834 7.24116 9.00972 7.24116C8.8811 7.24116 8.68817 7.24116 8.55956 7.24116C8.43094 7.24116 8.1094 7.27331 7.91647 7.5627C7.69139 7.81994 7.0483 8.43087 7.0483 9.65273C7.0483 10.8746 7.91647 12 8.07724 12.2251C8.20586 12.3537 9.84573 14.8939 12.2895 15.9871C12.8682 16.2444 13.3184 16.4051 13.7043 16.5338C14.283 16.7267 14.8297 16.6624 15.2477 16.6302C15.73 16.5981 16.6946 16.0514 16.9197 15.4405C17.1126 14.8939 17.1126 14.3473 17.0483 14.2508C16.984 14.1865 16.7911 14.09 16.566 13.9936Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
41
components/shared/locale-switcher.tsx
Normal file
41
components/shared/locale-switcher.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
'use client'
|
||||
|
||||
import {useLocale} from 'next-intl'
|
||||
import {redirect} from 'next/navigation'
|
||||
|
||||
import {Link, usePathname, useRouter} from '@/i18n/routing'
|
||||
import {Label} from '@/ui/label'
|
||||
import {Switch} from '@/ui/switch'
|
||||
|
||||
export default function LocaleSwitcher() {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const locale = useLocale()
|
||||
const initialState = locale !== 'uk'
|
||||
|
||||
const handler = (state: boolean) => {
|
||||
const newPath = `/${locale}${pathname}`
|
||||
//window.history.replaceState(null, '', newPath)
|
||||
const link = document.getElementById('lang-switch')
|
||||
if (link) {
|
||||
link.innerText = `${state ? '/ru' : ''}${pathname}`
|
||||
link.setAttribute('href', `${state ? '/ru' : ''}${pathname}`)
|
||||
link.click()
|
||||
}
|
||||
}
|
||||
// router.replace('/cabinet', {locale: checked ? 'ru' : 'uk'}
|
||||
return (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<Link id='lang-switch' href='/' locale='uk'>
|
||||
LA
|
||||
</Link>
|
||||
<Label htmlFor='locale-switcher'>Укр</Label>
|
||||
<Switch
|
||||
id='locale-switcher'
|
||||
defaultChecked={initialState}
|
||||
onCheckedChange={handler}
|
||||
/>
|
||||
<Label htmlFor='locale-switcher'>Рус</Label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
9
components/shared/navbar/index.tsx
Normal file
9
components/shared/navbar/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import NavbarMenu from '@/components/shared/navbar/navbar-menu'
|
||||
|
||||
export default function Navbar() {
|
||||
return (
|
||||
<nav className='text-min flex w-full items-center justify-between text-sm font-medium leading-none'>
|
||||
<NavbarMenu />
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
44
components/shared/navbar/navbar-menu.tsx
Normal file
44
components/shared/navbar/navbar-menu.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
'use client'
|
||||
|
||||
import {Menu as MenuIcon, X} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import {useState} from 'react'
|
||||
|
||||
import {data} from '@/lib/data'
|
||||
import {Button} from '@/ui/button'
|
||||
|
||||
export default function NavbarMenu() {
|
||||
const bp = 'md'
|
||||
|
||||
const [menuOpened, setMenuOpened] = useState(false)
|
||||
|
||||
function ToggleNavbar() {
|
||||
setMenuOpened(!menuOpened)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`hidden ${bp}:block w-full`}>
|
||||
<div className='flex items-center justify-between'>
|
||||
{data.headerMenus.map(item => (
|
||||
<Link href={item.href + item.slug} className='' key={item.name}>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`flex items-center ${bp}:hidden`}>
|
||||
<Button variant='ghost' onClick={ToggleNavbar}>
|
||||
{menuOpened ? <X /> : <MenuIcon />}
|
||||
</Button>
|
||||
</div>
|
||||
{menuOpened && (
|
||||
<div className={`${bp}:hidden`}>
|
||||
<div className='space-y-1 px-2 pb-3 pt-2'>
|
||||
<Link href={'#'}>Hidden Menu</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
33
components/shared/search/form.tsx
Normal file
33
components/shared/search/form.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import {SearchIcon} from 'lucide-react'
|
||||
import {getTranslations} from 'next-intl/server'
|
||||
import Form from 'next/form'
|
||||
|
||||
import {Button} from '@/ui/button'
|
||||
import {Input} from '@/ui/input'
|
||||
|
||||
export default async function SearchForm({query}: {query?: string}) {
|
||||
const t = await getTranslations('UI')
|
||||
|
||||
return (
|
||||
<Form
|
||||
action='/search'
|
||||
scroll={false}
|
||||
className='border-stone flex h-10 w-full overflow-hidden rounded-[10px] border-2'
|
||||
>
|
||||
<Input
|
||||
className='h-full flex-1 rounded-none border-0 bg-white text-base text-stone-600 outline-0 dark:border-gray-200'
|
||||
placeholder={t('search-placeholder')}
|
||||
name='query'
|
||||
defaultValue={query}
|
||||
type='text'
|
||||
/>
|
||||
<Button
|
||||
type='submit'
|
||||
className='h-full rounded-none border-none bg-neutral-200 px-3 py-2 text-stone-600'
|
||||
>
|
||||
{/*<SearchIcon className='size-5' />*/}
|
||||
{t('search-button')}
|
||||
</Button>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
55
components/shared/sidebar/app-catalog-render.tsx
Normal file
55
components/shared/sidebar/app-catalog-render.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
'use client'
|
||||
|
||||
import {useLocale} from 'next-intl'
|
||||
|
||||
import {Link} from '@/i18n/routing'
|
||||
import {Button} from '@/ui/button'
|
||||
|
||||
export default function AppCatalogRender(items: Array<object>) {
|
||||
const locale = useLocale()
|
||||
|
||||
return (
|
||||
<div className='flex w-full justify-center'>
|
||||
<div className='bw-dd-menu group inline-block w-full'>
|
||||
<Button className='py-13 flex h-10 w-full items-center rounded-sm border-none bg-brand-yellow-300 px-3 outline-none focus:outline-none'>
|
||||
<span className='flex-1 pr-1 font-semibold'>Каталог</span>
|
||||
<span>
|
||||
<svg
|
||||
className='h-4 w-4 transform fill-current transition duration-300 ease-in-out group-hover:-rotate-180'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 20 20'
|
||||
>
|
||||
<path d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' />
|
||||
</svg>
|
||||
</span>
|
||||
</Button>
|
||||
<ul className='-bw-app-catalog-collapse mt-2 w-full min-w-32 origin-top transform rounded-sm border bg-white shadow-xl transition duration-300 ease-in-out group-hover:scale-100 hover:shadow-2xl'>
|
||||
{items?.items.map((item: any) => (
|
||||
<li
|
||||
className='cursor-pointer rounded-none py-2.5 pl-3 pr-1.5 text-sm font-medium hover:bg-[#442d88]/10 xl:py-3'
|
||||
key={item.id}
|
||||
>
|
||||
<button className='flex w-full items-center text-left outline-none focus:outline-none'>
|
||||
<Link
|
||||
className='flex-1 pr-1 leading-none xl:leading-[1.3]'
|
||||
href={`/category/${item.id}-${item.locales[locale === 'uk' ? 0 : 1].slug}`}
|
||||
>
|
||||
{item.locales[locale === 'uk' ? 0 : 1].title}
|
||||
</Link>
|
||||
<span className='mr-auto'>
|
||||
<svg
|
||||
className='h-4 w-4 fill-current transition duration-150 ease-in-out'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 20 20'
|
||||
>
|
||||
<path d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
16
components/shared/sidebar/app-catalog.tsx
Normal file
16
components/shared/sidebar/app-catalog.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
'use server'
|
||||
|
||||
import AppCatalogRender from '@/components/shared/sidebar/app-catalog-render'
|
||||
import {db} from '@/lib/db/prisma/client'
|
||||
|
||||
const appCatalog = async () => {
|
||||
return db.category.findMany({
|
||||
include: {
|
||||
locales: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default async function AppCatalog() {
|
||||
return <AppCatalogRender items={await appCatalog()} />
|
||||
}
|
||||
82
components/shared/social-media-panel.tsx
Normal file
82
components/shared/social-media-panel.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import IconProps from '@/components/shared/icons/props'
|
||||
import WhatsappIcon from '@/components/shared/icons/whatsapp'
|
||||
import {BRAND_ICON_COLOR, BRAND_ICON_SIZE} from '@/lib/constants'
|
||||
import {cn} from '@/lib/utils'
|
||||
|
||||
export default function SocialMediaPanel({className, size, color}: IconProps) {
|
||||
return (
|
||||
<aside className={cn('flex items-center gap-x-4', className)}>
|
||||
{/*facebook*/}
|
||||
<div>
|
||||
<svg
|
||||
width={size || BRAND_ICON_SIZE}
|
||||
height={size || BRAND_ICON_SIZE * 1.041666666666667}
|
||||
viewBox='0 0 24 25'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M12 2.53906C17.5229 2.53906 22 7.01621 22 12.5391C22 17.5304 18.3431 21.6674 13.5625 22.4176V15.4297H15.8926L16.3359 12.5391L13.5625 12.5387V10.6632C13.5625 10.657 13.5625 10.6509 13.5626 10.6447C13.5626 10.6354 13.5628 10.6262 13.5629 10.6169C13.578 9.84259 13.9742 9.10156 15.1921 9.10156H16.4531V6.64062C16.4531 6.64062 15.3087 6.44492 14.2146 6.44492C11.966 6.44492 10.4842 7.78652 10.4386 10.2193C10.4379 10.2578 10.4375 10.2965 10.4375 10.3355V12.5387H7.89844V15.4293L10.4375 15.4297V22.4172C5.65686 21.667 2 17.5304 2 12.5391C2 7.01621 6.47715 2.53906 12 2.53906Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<WhatsappIcon size={size} color={color} />
|
||||
</div>
|
||||
|
||||
{/*Telegram*/}
|
||||
<div>
|
||||
<svg
|
||||
width={size || BRAND_ICON_SIZE}
|
||||
height={size || BRAND_ICON_SIZE}
|
||||
viewBox='0 0 24 24'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M21.936 5.17077L18.9059 19.3546C18.6802 20.3539 18.1 20.5795 17.2618 20.1282L12.7166 16.7757L10.4923 18.9033C10.2666 19.1289 10.041 19.3546 9.5252 19.3546L9.8798 14.6804L18.3578 6.97598C18.7124 6.62138 18.2611 6.49244 17.8098 6.78256L7.26869 13.4232L2.72343 12.037C1.72412 11.7147 1.72412 11.0377 2.94908 10.5864L20.6144 3.72015C21.4847 3.46227 22.2262 3.91357 21.936 5.17077Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/*Instagram*/}
|
||||
<div>
|
||||
<svg
|
||||
width={size || BRAND_ICON_SIZE}
|
||||
height={size || BRAND_ICON_SIZE}
|
||||
viewBox='0 0 24 24'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M8.6672 12C8.6672 10.1591 10.1591 8.6664 12 8.6664C13.8409 8.6664 15.3336 10.1591 15.3336 12C15.3336 13.8409 13.8409 15.3336 12 15.3336C10.1591 15.3336 8.6672 13.8409 8.6672 12ZM6.86512 12C6.86512 14.836 9.164 17.1349 12 17.1349C14.836 17.1349 17.1349 14.836 17.1349 12C17.1349 9.164 14.836 6.86512 12 6.86512C9.164 6.86512 6.86512 9.164 6.86512 12ZM16.1382 6.66152C16.1381 6.89886 16.2084 7.13089 16.3401 7.32829C16.4719 7.52568 16.6593 7.67956 16.8785 7.77047C17.0977 7.86138 17.339 7.88525 17.5718 7.83904C17.8046 7.79283 18.0185 7.67862 18.1863 7.51087C18.3542 7.34311 18.4686 7.12934 18.515 6.89658C18.5614 6.66382 18.5377 6.42253 18.447 6.20322C18.3563 5.98392 18.2025 5.79644 18.0052 5.6645C17.808 5.53257 17.576 5.4621 17.3386 5.462H17.3382C17.02 5.46215 16.715 5.58856 16.49 5.81347C16.265 6.03837 16.1384 6.34339 16.1382 6.66152ZM7.96 20.1398C6.98504 20.0954 6.45512 19.933 6.10296 19.7958C5.63608 19.614 5.30296 19.3975 4.95272 19.0478C4.60248 18.698 4.38568 18.3652 4.20472 17.8983C4.06744 17.5463 3.90504 17.0162 3.86072 16.0413C3.81224 14.9872 3.80256 14.6706 3.80256 12.0001C3.80256 9.3296 3.81304 9.01384 3.86072 7.95888C3.90512 6.98392 4.06872 6.45488 4.20472 6.10184C4.38648 5.63496 4.60296 5.30184 4.95272 4.9516C5.30248 4.60136 5.63528 4.38456 6.10296 4.2036C6.45496 4.06632 6.98504 3.90392 7.96 3.8596C9.01408 3.81112 9.33072 3.80144 12 3.80144C14.6693 3.80144 14.9862 3.81192 16.0412 3.8596C17.0162 3.904 17.5452 4.0676 17.8982 4.2036C18.3651 4.38456 18.6982 4.60184 19.0485 4.9516C19.3987 5.30136 19.6147 5.63496 19.7965 6.10184C19.9338 6.45384 20.0962 6.98392 20.1405 7.95888C20.189 9.01384 20.1986 9.3296 20.1986 12.0001C20.1986 14.6706 20.189 14.9863 20.1405 16.0413C20.0961 17.0162 19.9329 17.5462 19.7965 17.8983C19.6147 18.3652 19.3982 18.6983 19.0485 19.0478C18.6987 19.3972 18.3651 19.614 17.8982 19.7958C17.5462 19.933 17.0162 20.0954 16.0412 20.1398C14.9871 20.1882 14.6705 20.1979 12 20.1979C9.32952 20.1979 9.01376 20.1882 7.96 20.1398ZM7.8772 2.06056C6.81264 2.10904 6.0852 2.27784 5.44992 2.52504C4.792 2.78032 4.23504 3.1228 3.67848 3.67848C3.12192 4.23416 2.78032 4.792 2.52504 5.44992C2.27784 6.0856 2.10904 6.81264 2.06056 7.8772C2.01128 8.94344 2 9.28432 2 12C2 14.7157 2.01128 15.0566 2.06056 16.1228C2.10904 17.1874 2.27784 17.9144 2.52504 18.5501C2.78032 19.2076 3.122 19.7661 3.67848 20.3215C4.23496 20.877 4.792 21.219 5.44992 21.475C6.0864 21.7222 6.81264 21.891 7.8772 21.9394C8.944 21.9879 9.28432 22 12 22C14.7157 22 15.0566 21.9887 16.1228 21.9394C17.1874 21.891 17.9144 21.7222 18.5501 21.475C19.2076 21.219 19.765 20.8772 20.3215 20.3215C20.8781 19.7658 21.219 19.2076 21.475 18.5501C21.7222 17.9144 21.8918 17.1874 21.9394 16.1228C21.9879 15.0558 21.9992 14.7157 21.9992 12C21.9992 9.28432 21.9879 8.94344 21.9394 7.8772C21.891 6.81256 21.7222 6.0852 21.475 5.44992C21.219 4.7924 20.8772 4.23504 20.3215 3.67848C19.7658 3.12192 19.2076 2.78032 18.5509 2.52504C17.9144 2.27784 17.1874 2.10824 16.1236 2.06056C15.0574 2.01208 14.7165 2 12.0008 2C9.28512 2 8.944 2.01128 7.8772 2.06056Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
<path
|
||||
d='M8.6672 12C8.6672 10.1591 10.1591 8.6664 12 8.6664C13.8409 8.6664 15.3336 10.1591 15.3336 12C15.3336 13.8409 13.8409 15.3336 12 15.3336C10.1591 15.3336 8.6672 13.8409 8.6672 12ZM6.86512 12C6.86512 14.836 9.164 17.1349 12 17.1349C14.836 17.1349 17.1349 14.836 17.1349 12C17.1349 9.164 14.836 6.86512 12 6.86512C9.164 6.86512 6.86512 9.164 6.86512 12ZM16.1382 6.66152C16.1381 6.89886 16.2084 7.13089 16.3401 7.32829C16.4719 7.52568 16.6593 7.67956 16.8785 7.77047C17.0977 7.86138 17.339 7.88525 17.5718 7.83904C17.8046 7.79283 18.0185 7.67862 18.1863 7.51087C18.3542 7.34311 18.4686 7.12934 18.515 6.89658C18.5614 6.66382 18.5377 6.42253 18.447 6.20322C18.3563 5.98392 18.2025 5.79644 18.0052 5.6645C17.808 5.53257 17.576 5.4621 17.3386 5.462H17.3382C17.02 5.46215 16.715 5.58856 16.49 5.81347C16.265 6.03837 16.1384 6.34339 16.1382 6.66152ZM7.96 20.1398C6.98504 20.0954 6.45512 19.933 6.10296 19.7958C5.63608 19.614 5.30296 19.3975 4.95272 19.0478C4.60248 18.698 4.38568 18.3652 4.20472 17.8983C4.06744 17.5463 3.90504 17.0162 3.86072 16.0413C3.81224 14.9872 3.80256 14.6706 3.80256 12.0001C3.80256 9.3296 3.81304 9.01384 3.86072 7.95888C3.90512 6.98392 4.06872 6.45488 4.20472 6.10184C4.38648 5.63496 4.60296 5.30184 4.95272 4.9516C5.30248 4.60136 5.63528 4.38456 6.10296 4.2036C6.45496 4.06632 6.98504 3.90392 7.96 3.8596C9.01408 3.81112 9.33072 3.80144 12 3.80144C14.6693 3.80144 14.9862 3.81192 16.0412 3.8596C17.0162 3.904 17.5452 4.0676 17.8982 4.2036C18.3651 4.38456 18.6982 4.60184 19.0485 4.9516C19.3987 5.30136 19.6147 5.63496 19.7965 6.10184C19.9338 6.45384 20.0962 6.98392 20.1405 7.95888C20.189 9.01384 20.1986 9.3296 20.1986 12.0001C20.1986 14.6706 20.189 14.9863 20.1405 16.0413C20.0961 17.0162 19.9329 17.5462 19.7965 17.8983C19.6147 18.3652 19.3982 18.6983 19.0485 19.0478C18.6987 19.3972 18.3651 19.614 17.8982 19.7958C17.5462 19.933 17.0162 20.0954 16.0412 20.1398C14.9871 20.1882 14.6705 20.1979 12 20.1979C9.32952 20.1979 9.01376 20.1882 7.96 20.1398ZM7.8772 2.06056C6.81264 2.10904 6.0852 2.27784 5.44992 2.52504C4.792 2.78032 4.23504 3.1228 3.67848 3.67848C3.12192 4.23416 2.78032 4.792 2.52504 5.44992C2.27784 6.0856 2.10904 6.81264 2.06056 7.8772C2.01128 8.94344 2 9.28432 2 12C2 14.7157 2.01128 15.0566 2.06056 16.1228C2.10904 17.1874 2.27784 17.9144 2.52504 18.5501C2.78032 19.2076 3.122 19.7661 3.67848 20.3215C4.23496 20.877 4.792 21.219 5.44992 21.475C6.0864 21.7222 6.81264 21.891 7.8772 21.9394C8.944 21.9879 9.28432 22 12 22C14.7157 22 15.0566 21.9887 16.1228 21.9394C17.1874 21.891 17.9144 21.7222 18.5501 21.475C19.2076 21.219 19.765 20.8772 20.3215 20.3215C20.8781 19.7658 21.219 19.2076 21.475 18.5501C21.7222 17.9144 21.8918 17.1874 21.9394 16.1228C21.9879 15.0558 21.9992 14.7157 21.9992 12C21.9992 9.28432 21.9879 8.94344 21.9394 7.8772C21.891 6.81256 21.7222 6.0852 21.475 5.44992C21.219 4.7924 20.8772 4.23504 20.3215 3.67848C19.7658 3.12192 19.2076 2.78032 18.5509 2.52504C17.9144 2.27784 17.1874 2.10824 16.1236 2.06056C15.0574 2.01208 14.7165 2 12.0008 2C9.28512 2 8.944 2.01128 7.8772 2.06056Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/*Youtube*/}
|
||||
<div>
|
||||
<svg
|
||||
width={((size || BRAND_ICON_SIZE) as number) * 1.5}
|
||||
height={((size || BRAND_ICON_SIZE) as number) * 1.5}
|
||||
viewBox='0 0 24 24'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M21.5806 7.19355C21.3548 6.32258 20.6774 5.64516 19.8065 5.41935C18.2581 5 12 5 12 5C12 5 5.74194 5 4.19355 5.41935C3.32258 5.64516 2.64516 6.32258 2.41935 7.19355C2 8.77419 2 12 2 12C2 12 2 15.2581 2.41935 16.8065C2.64516 17.6774 3.32258 18.3548 4.19355 18.5806C5.74194 19 12 19 12 19C12 19 18.2581 19 19.8065 18.5806C20.6774 18.3548 21.3548 17.6774 21.5806 16.8065C22 15.2581 22 12 22 12C22 12 22 8.77419 21.5806 7.19355ZM10 15V9L15.1935 12L10 15Z'
|
||||
fill={color || BRAND_ICON_COLOR}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
30
components/shared/store/product-card.tsx
Normal file
30
components/shared/store/product-card.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
|
||||
import {Card, CardContent, CardFooter} from '@/ui/card'
|
||||
|
||||
export type CardItem = {
|
||||
title: string
|
||||
image: string
|
||||
href: string
|
||||
price: number
|
||||
}
|
||||
|
||||
export default function ProductCard({card}: {card: CardItem}) {
|
||||
return (
|
||||
<Card key={card.title} className='flex flex-col'>
|
||||
<Link key={card.title} href={card.href} className='flex flex-col'>
|
||||
<CardContent className='flex-1 p-4'>
|
||||
<Image
|
||||
src={card.image}
|
||||
alt={card.title}
|
||||
width={120}
|
||||
height={120}
|
||||
className='aspect-card mx-auto h-auto max-w-full object-cover'
|
||||
/>
|
||||
</CardContent>
|
||||
<CardFooter>{card.title}</CardFooter>
|
||||
</Link>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user