This commit is contained in:
Joel Varty
2021-06-17 17:37:32 -04:00
parent d48aec2c2d
commit d9fe7d8e6b
23 changed files with 263 additions and 11789 deletions

View File

@@ -5,7 +5,7 @@ import { Grid, Marquee, Hero } from '@components/ui'
import { ModuleWithInit } from '@agility/nextjs'
interface ICustomData {
bestSelling: any
products: any
}
interface IModule {
@@ -14,21 +14,14 @@ interface IModule {
const BestsellingProducts: ModuleWithInit<IModule, ICustomData> = ({ customData }) => {
const bestSelling = customData.bestSelling
const products = customData.products
return (
<Marquee variant="secondary">
{bestSelling.slice(0, 12).map(({ node }: any) => (
<ProductCard
key={node.path}
product={node}
variant="slim"
imgWidth={320}
imgHeight={320}
imgLayout="fixed"
/>
))}
</Marquee>
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>
)
}

View File

@@ -1,13 +1,12 @@
import React, { FC } from 'react'
import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
import useCart from '@framework/cart/use-cart'
import usePrice from '@framework/use-price'
import { Button } from '@components/ui'
import { Bag, Cross, Check } from '@components/icons'
import usePrice from '@framework/product/use-price'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Button, Text } from '@components/ui'
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
import { CartItem } from '@components/cart'
import { Text } from '@components/ui'
interface Fields {
}
@@ -18,39 +17,37 @@ interface Props {
}
const Cart: FC<Props> = ({ fields, customData }) => {
const { data, isEmpty } = useCart()
const error = null
const success = null
const { data, isLoading, isEmpty } = useCart()
const { price: subTotal } = usePrice(
data && {
amount: data.base_amount,
amount: Number(data.subtotalPrice),
currencyCode: data.currency.code,
}
)
const { price: total } = usePrice(
data && {
amount: data.cart_amount,
amount: Number(data.totalPrice),
currencyCode: data.currency.code,
}
)
const items = data?.line_items.physical_items ?? []
const error = null
const success = null
return (
<div className="grid lg:grid-cols-12">
<div className="grid lg:grid-cols-12 w-full max-w-7xl mx-auto">
<div className="lg:col-span-8">
{isEmpty ? (
{isLoading || isEmpty ? (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Bag className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
</h2>
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</p>
</div>
) : error ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
@@ -60,7 +57,7 @@ const Cart: FC<Props> = ({ fields, customData }) => {
<h2 className="pt-6 text-xl font-light text-center">
We couldnt process the purchase. Please check your card
information and try again.
</h2>
</h2>
</div>
) : success ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
@@ -69,14 +66,14 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</span>
<h2 className="pt-6 text-xl font-light text-center">
Thank you for your order.
</h2>
</h2>
</div>
) : (
<div className="px-4 sm:px-6 flex-1">
<Text variant="pageHeading">My Cart</Text>
<Text variant="sectionHeading">Review your Order</Text>
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accents-2 border-b border-accents-2">
{items.map((item) => (
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-b border-accent-2">
{data!.lineItems.map((item: any) => (
<CartItem
key={item.id}
item={item}
@@ -91,7 +88,10 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</Text>
<div className="flex py-6 space-x-6">
{[1, 2, 3, 4, 5, 6].map((x) => (
<div className="border border-accents-3 w-full h-24 bg-accents-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75" />
<div
key={x}
className="border border-accent-3 w-full h-24 bg-accent-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
/>
))}
</div>
</div>
@@ -100,7 +100,36 @@ const Cart: FC<Props> = ({ fields, customData }) => {
</div>
<div className="lg:col-span-4">
<div className="flex-shrink-0 px-4 py-24 sm:px-6">
<div className="border-t border-accents-2">
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED && (
<>
{/* Shipping Address */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<MapPin />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Shipping Address</span>
{/* <span>
1046 Kearny Street.<br/>
San Franssisco, California
</span> */}
</div>
</div>
{/* Payment Method */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<CreditCard />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Payment Method</span>
{/* <span>VISA #### #### #### 2345</span> */}
</div>
</div>
</>
)}
<div className="border-t border-accent-2">
<ul className="py-3">
<li className="flex justify-between py-1">
<span>Subtotal</span>
@@ -115,7 +144,7 @@ const Cart: FC<Props> = ({ fields, customData }) => {
<span className="font-bold tracking-wide">FREE</span>
</li>
</ul>
<div className="flex justify-between border-t border-accents-2 py-3 font-bold mb-10">
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-10">
<span>Total</span>
<span>{total}</span>
</div>
@@ -127,10 +156,10 @@ const Cart: FC<Props> = ({ fields, customData }) => {
Continue Shopping
</Button>
) : (
<Button href="/checkout" Component="a" width="100%">
Proceed to Checkout
</Button>
)}
<Button href="/checkout" Component="a" width="100%">
Proceed to Checkout
</Button>
)}
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@ import { ProductCard } from '@components/product'
import { ModuleWithInit } from "@agility/nextjs"
interface ICustomData {
featured: any
products: any
}
interface IModule {
@@ -17,16 +17,18 @@ const FeaturedProducts: ModuleWithInit<IModule, ICustomData> = ({ customData })
return <div>No featured products returned.</div>
}
const featured:any = customData.featured
const products:any = customData.products
return (
<Grid layout="B">
{featured.map(({ node }:any, i:number) => (
<Grid variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={node.path}
product={node}
imgWidth={i === 1 ? 1080 : 540}
imgHeight={i === 1 ? 1080 : 540}
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
}}
/>
))}
</Grid>

View File

@@ -1,13 +1,13 @@
import React, { FC } from 'react'
import { Hero } from '@components/ui'
import * as AgilityTypes from "@agility/types"
import { URLField } from "@agility/nextjs"
import { Module } from '@agility/nextjs'
interface Fields {
title:string,
description:string
cTA?:AgilityTypes.URLField
cTA?:URLField
}
const HeroModule:Module<Fields> = ({ module: {fields }}) => {

View File

@@ -1,13 +1,14 @@
import React, { FC } from 'react'
import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
import { ModuleWithInit } from '@agility/nextjs'
import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
interface ICustomData {
categories: any
newestProducts: any
brands: any
products: any
}
interface IModule {
@@ -16,19 +17,25 @@ interface IModule {
const HomeAllProductsGridModule: ModuleWithInit<IModule, ICustomData> = ({ customData }) => {
const categories = customData.categories
const newestProducts = customData.newestProducts
const brands = customData.brands
if (!categories) return <div>No data</div>
const products = customData.products
return (
<HomeAllProductsGrid
categories={categories}
brands={brands}
newestProducts={newestProducts}
/>
<Grid layout="B" variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
}}
/>
))}
</Grid>
)
}
export default HomeAllProductsGridModule

View File

@@ -8,7 +8,7 @@ import { Module } from '@agility/nextjs'
interface Fields {
}
const Orders: Module<Fields> = ({ }) => {
const Orders: Module<Fields> = ({ }) => {
return (
<Container>
<Text variant="pageHeading">My Orders</Text>
@@ -19,8 +19,8 @@ const Orders: Module<Fields> = ({ }) => {
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
No orders found
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
Orders coming soon!
<p className="text-accent-6 px-10 text-center pt-2">
Orders coming soon.
</p>
</div>
</Container>

View File

@@ -1,20 +1,25 @@
import React, { FC } from 'react'
import { Hero } from '@components/ui'
import * as AgilityTypes from "@agility/types"
import { GetProductResult } from '@framework/api/operations/get-product'
import { ProductView } from '@components/product'
import { Module } from '@agility/nextjs'
interface Fields {
import { ProductView } from '@components/product'
import { Module, ModuleWithInit } from '@agility/nextjs'
interface IFields {
}
interface ICustomData {
products: any
}
const HeroModule:Module<Fields> = ({ dynamicPageItem }) => {
const ProductDetails:ModuleWithInit<IFields, ICustomData> = ({ dynamicPageItem, customData }) => {
const product:any = dynamicPageItem
const relatedProducts:[] = customData.products
return (
<ProductView product={product} />
<ProductView product={product} relatedProducts={relatedProducts} />
)
}
export default HeroModule
export default ProductDetails

View File

@@ -1,31 +1,7 @@
import React, { FC } from 'react'
import cn from 'classnames'
import Link from 'next/link'
import { useState } from 'react'
import { useRouter } from 'next/router'
import useSearch from '@framework/products/use-search'
import { ProductCard } from '@components/product'
import { Container, Grid, Skeleton } from '@components/ui'
import rangeMap from '@lib/range-map'
import getSlug from '@lib/get-slug'
import {
filterQuery,
getCategoryPath,
getDesignerPath,
useSearchMeta,
} from '@lib/search'
import Search from '@components/search'
import { ModuleWithInit } from '@agility/nextjs'
const SORT = Object.entries({
'latest-desc': 'Latest arrivals',
'trending-desc': 'Trending',
'price-asc': 'Price: Low to high',
'price-desc': 'Price: High to low',
})
interface ICustomData {
categories: any
brands: any
@@ -40,416 +16,8 @@ const ProductSearch: ModuleWithInit<IModule, ICustomData> = ({ customData }) =>
const categories:[any] = customData.categories
const brands:[any] = customData.brands
const [activeFilter, setActiveFilter] = useState('')
const [toggleFilter, setToggleFilter] = useState(false)
return <Search brands={brands} categories={categories} pages={[]} />
const router = useRouter()
const { asPath } = router
const { q, sort } = router.query
// `q` can be included but because categories and designers can't be searched
// in the same way of products, it's better to ignore the search input if one
// of those is selected
const query = filterQuery({ sort })
const { pathname, category, brand } = useSearchMeta(asPath)
const activeCategory = categories.find(
(cat) => getSlug(cat.path) === category
)
const activeBrand = brands.find(
(b) => getSlug(b.node.path) === `brands/${brand}`
)?.node
const { data } = useSearch({
search: typeof q === 'string' ? q : '',
categoryId: activeCategory?.entityId,
brandId: activeBrand?.entityId,
sort: typeof sort === 'string' ? sort : '',
})
const handleClick = (event: any, filter: string) => {
if (filter !== activeFilter) {
setToggleFilter(true)
} else {
setToggleFilter(!toggleFilter)
}
setActiveFilter(filter)
}
return (
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-4 mt-3 mb-20">
<div className="col-span-8 lg:col-span-2 order-1 lg:order-none">
{/* Categories */}
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'categories')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeCategory?.name
? `Category: ${activeCategory?.name}`
: 'All Categories'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'categories' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeCategory?.name,
}
)}
>
<Link
href={{ pathname: getCategoryPath('', brand), query }}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Categories
</a>
</Link>
</li>
{categories.map((cat) => (
<li
key={cat.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline:
activeCategory?.entityId === cat.entityId,
}
)}
>
<Link
href={{
pathname: getCategoryPath(cat.path, brand),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{cat.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
{/* Designs */}
<div className="relative inline-block w-full">
<div className="lg:hidden mt-3">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'brands')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-900 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeBrand?.name
? `Design: ${activeBrand?.name}`
: 'All Designs'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'brands' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeBrand?.name,
}
)}
>
<Link
href={{
pathname: getDesignerPath('', category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Designers
</a>
</Link>
</li>
{brands.flatMap(({ node }) => (
<li
key={node.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: activeBrand?.entityId === node.entityId,
}
)}
>
<Link
href={{
pathname: getDesignerPath(node.path, category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{node.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
{/* Products */}
<div className="col-span-8 order-3 lg:order-none">
{(q || activeCategory || activeBrand) && (
<div className="mb-12 transition ease-in duration-75">
{data ? (
<>
<span
className={cn('animated', {
fadeIn: data.found,
hidden: !data.found,
})}
>
Showing {data.products.length} results{' '}
{q && (
<>
for "<strong>{q}</strong>"
</>
)}
</span>
<span
className={cn('animated', {
fadeIn: !data.found,
hidden: data.found,
})}
>
{q ? (
<>
There are no products that match "<strong>{q}</strong>"
</>
) : (
<>
There are no products that match the selected category &
designer
</>
)}
</span>
</>
) : q ? (
<>
Searching for: "<strong>{q}</strong>"
</>
) : (
<>Searching...</>
)}
</div>
)}
{data ? (
<Grid layout="normal">
{data.products.map(({ node }) => (
<ProductCard
variant="simple"
key={node.path}
className="animated fadeIn"
product={node}
imgWidth={480}
imgHeight={480}
/>
))}
</Grid>
) : (
<Grid layout="normal">
{rangeMap(12, (i) => (
<Skeleton
key={i}
className="w-full animated fadeIn"
height={325}
/>
))}
</Grid>
)}
</div>
{/* Sort */}
<div className="col-span-8 lg:col-span-2 order-2 lg:order-none">
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'sort')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{sort ? `Sort: ${sort}` : 'Relevance'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'sort' || toggleFilter !== true ? 'hidden' : ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !sort,
}
)}
>
<Link href={{ pathname, query: filterQuery({ q }) }}>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
Relevance
</a>
</Link>
</li>
{SORT.map(([key, text]) => (
<li
key={key}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: sort === key,
}
)}
>
<Link
href={{
pathname,
query: filterQuery({ q, sort: key }),
}}
>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{text}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</Container>
)
}

View File

@@ -1,6 +1,6 @@
import React, { FC } from 'react'
import useCustomer from '@framework/use-customer'
import useCustomer from '@framework/customer/use-customer'
import { Container, Text } from '@components/ui'
import { Module } from '@agility/nextjs'
@@ -12,34 +12,30 @@ interface Fields {
}
const ProfileModule:Module<Fields> = ({ module: {fields}}) => {
const ProfileModule: Module<Fields> = ({ module: { fields } }) => {
const { data } = useCustomer()
return (
<Container>
<Text variant="pageHeading">{fields.heading}</Text>
{data && (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8 pr-4">
<div>
<Text variant="sectionHeading">{fields.fullNameLabel}</Text>
<span>
{data.firstName} {data.lastName}
</span>
</div>
<div className="mt-5">
<Text variant="sectionHeading">{fields.emailLabel}</Text>
<span>{data.email}</span>
</div>
</div>
</div>
)}
{ !data &&
<Text variant="body">{fields.notLoggedInMessage}</Text>
}
</Container>
)
return (
<Container>
<Text variant="pageHeading">My Profile</Text>
{data && (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8 pr-4">
<div>
<Text variant="sectionHeading">Full Name</Text>
<span>
{data.firstName} {data.lastName}
</span>
</div>
<div className="mt-5">
<Text variant="sectionHeading">Email</Text>
<span>{data.email}</span>
</div>
</div>
</div>
)}
</Container>
)
}
export default ProfileModule