Skip to content

Commit

Permalink
build summary component
Browse files Browse the repository at this point in the history
  • Loading branch information
mapra99 committed Dec 19, 2022
1 parent ccbfa47 commit 601d55e
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 14 deletions.
3 changes: 3 additions & 0 deletions app/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ export { default as PurchaseCartModal } from './purchase-cart-modal'
export { default as PurchaseCartList } from './purchase-cart-list'
export { default as EmptyPurchaseCartList } from './empty-purchase-cart-list'
export { default as PurchaseCartListItem } from './purchase-cart-list-item'
export { default as PurchaseCartSummary } from './purchase-cart-summary'
export { default as PurchaseCartSummaryItem } from './purchase-cart-summary-item'
export { default as PurchaseCartSummaryFee } from './purchase-cart-summary-fee'
2 changes: 1 addition & 1 deletion app/components/purchase-cart-list/purchase-cart-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const PurchaseCartList = ({ cart, onClose }: PurchaseCartListProps) => {
</Text>
</div>

<ButtonLink variant="primary" to="/checkout" className="text-center">
<ButtonLink variant="primary" to="/checkout" className="text-center" onClick={onClose}>
Checkout
</ButtonLink>
</div>
Expand Down
1 change: 1 addition & 0 deletions app/components/purchase-cart-summary-fee/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './purchase-cart-summary-fee'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Text } from '~/components'
import formatCurrency from '~/utils/format-currency'

import type { PurchaseCartSummaryFeeProps } from './types'

const PurchaseCartSummaryFee = ({ label, value }: PurchaseCartSummaryFeeProps) => {
return (
<div className="flex justify-between">
<Text variant="body" as="span" className="text-black opacity-50 uppercase font-medium">
{ label }
</Text>

<Text variant="body" as="span" className="!font-bold">
{ formatCurrency(value) }
</Text>
</div>
)
}

export default PurchaseCartSummaryFee
4 changes: 4 additions & 0 deletions app/components/purchase-cart-summary-fee/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PurchaseCartSummaryFeeProps {
label: string
value: number
}
1 change: 1 addition & 0 deletions app/components/purchase-cart-summary-item/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './purchase-cart-summary-item'
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Text } from '~/components'
import formatCurrency from '~/utils/format-currency'

import type { PurchaseCartSummaryItemProps } from './types'

const PurchaseCartSummaryItem = ({ cartItem }: PurchaseCartSummaryItemProps) => {
const { uuid, stock: { product }, unit_price, quantity } = cartItem

return (
<div key={uuid} className="flex gap-4 items-center">
<div className="rounded-lg bg-gray w-16 h-16 flex items-center justify-center flex-none">
{ product.image && (
<img src={product.image.url} alt="" className="block w-9" />
) }
</div>

<div className="flex flex-col flex-1 overflow-hidden">
<Text variant="body" className="!font-bold text-ellipsis overflow-hidden" as="span">
{ product.name }
</Text>
<Text variant="body" className="!font-bold text-black opacity-50 text-ellipsis overflow-hidden" as="span">
{ formatCurrency(unit_price) }
</Text>
</div>

<div className="flex-none opacity-50 font-bold">
x{quantity}
</div>
</div>
)
}

export default PurchaseCartSummaryItem
5 changes: 5 additions & 0 deletions app/components/purchase-cart-summary-item/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { PurchaseCartItem } from '~/models/purchase-cart'

export interface PurchaseCartSummaryItemProps {
cartItem: PurchaseCartItem
}
1 change: 1 addition & 0 deletions app/components/purchase-cart-summary/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './purchase-cart-summary'
48 changes: 48 additions & 0 deletions app/components/purchase-cart-summary/purchase-cart-summary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Text, PurchaseCartSummaryItem, PurchaseCartSummaryFee } from '~/components'
import formatCurrency from '~/utils/format-currency'

import type { PurchaseCartSummaryProps } from './types'

const PurchaseCartSummary = ({ cart }: PurchaseCartSummaryProps) => {
const { items, extra_fees, total_price } = cart
const partialTotal = items.reduce((cumSum, item) => cumSum + item.price, 0)

return (
<div className="rounded-lg bg-white px-6 py-8 sm:p-8">
<Text variant="heading-6" className="mb-8" as="h2">
Summary
</Text>

<div className="flex flex-col gap-6 mb-8">
{ items.map(cartItem => (
<PurchaseCartSummaryItem
key={cartItem.uuid}
cartItem={cartItem}
/>
))}
</div>

<div className="flex flex-col gap-2 mb-6">
<PurchaseCartSummaryFee
label="Total"
value={partialTotal}
/>

{ extra_fees.map((extra_fee) => (
<PurchaseCartSummaryFee
key={extra_fee.key}
label={extra_fee.key}
value={extra_fee.price}
/>
)) }
</div>

<PurchaseCartSummaryFee
label="Grand Total"
value={total_price}
/>
</div>
)
}

export default PurchaseCartSummary
5 changes: 5 additions & 0 deletions app/components/purchase-cart-summary/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { PurchaseCart } from '~/models/purchase-cart'

export interface PurchaseCartSummaryProps {
cart: PurchaseCart
}
42 changes: 29 additions & 13 deletions app/routes/checkout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import { Outlet } from '@remix-run/react'
import { Text } from '~/components'
import { Outlet, useLoaderData } from '@remix-run/react'
import { json } from '@remix-run/node'
import invariant from 'tiny-invariant'
import { Text, PurchaseCartSummary } from '~/components'
import { getLastStartedCart } from '~/models/purchase-cart'
import * as SessionStorage from '~/utils/session-storage'

import type { LoaderArgs } from '@remix-run/node'

export const loader = async ({ request }: LoaderArgs) => {
const { sessionId } = await SessionStorage.getOrCreateSessionId(request)

const activeCart = await getLastStartedCart(sessionId)
invariant(activeCart, 'There must be an existing started cart')

return json({ activeCart })
}

export default () => {
const { activeCart } = useLoaderData()
const goBack = () => history.back()

return (
Expand All @@ -14,19 +30,19 @@ export default () => {
</div>
</div>

<div className="px-6 pb-24 sm:px-10 sm:pb-28 flex flex-col gap-8">
<div className="rounded-lg bg-white px-6 py-8 sm:p-8">
<Text variant="heading-3" className="!text-3xl sm:!text-4xl mb-8" as="h2">
Checkout
</Text>
<div className="px-6 pb-24 sm:px-10 sm:pb-28">
<div className="max-w-6xl mx-auto flex flex-col gap-8 lg:flex-row">
<div className="rounded-lg bg-white px-6 py-8 sm:p-8 lg:flex-1 lg:pt-14 lg:px-12 lg:pb-12">
<Text variant="heading-3" className="!text-3xl sm:!text-4xl mb-8 sm:mb-10" as="h2">
Checkout
</Text>

<Outlet />
</div>
<Outlet />
</div>

<div className="rounded-lg bg-white px-6 py-8 sm:p-8">
<Text variant="heading-6" className="mb-8" as="h2">
Summary
</Text>
<div className="lg:flex-0.5">
<PurchaseCartSummary cart={activeCart} />
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 601d55e

Please sign in to comment.