Skip to content
This repository has been archived by the owner on Jul 10, 2023. It is now read-only.

Commit

Permalink
Adds gift card details (#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivermrbl authored Feb 5, 2022
1 parent 8700a49 commit 12c04a8
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 13 deletions.
33 changes: 23 additions & 10 deletions src/components/templates/gift-card-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import moment from "moment"
import React, { useEffect, useState } from "react"
import { formatAmountWithSymbol } from "../../../utils/prices"
import StatusIndicator from "../../fundamentals/status-indicator"
import InfoTooltip from "../../molecules/info-tooltip"
import Table from "../../molecules/table"
import { FilteringOptionProps } from "../../molecules/table/filtering-option"

Expand Down Expand Up @@ -112,20 +114,31 @@ const GiftCardTable: React.FC<GiftCardTableProps> = ({ giftCards }) => {
{giftCard.order && `# ${giftCard.order.display_id}`}
</Table.Cell>
<Table.Cell className="">
{(giftCard.value &&
`${(
((1 + giftCard.region.tax_rate / 100) * giftCard.value) /
100
).toFixed(2)} ${giftCard.region.currency_code.toUpperCase()}`) || (
<>&nbsp;</>
{giftCard?.region ? (
formatAmountWithSymbol({
amount: giftCard.value,
currency: giftCard.region.currency_code,
})
) : (
<div className="flex items-center space-x-2">
<span>N / A</span>
<InfoTooltip content={"Region has been deleted"} />
</div>
)}
</Table.Cell>
<Table.Cell className="">
{giftCard.balance ? (
`${(
((1 + giftCard.region.tax_rate / 100) * giftCard.balance) /
100
).toFixed(2)} ${giftCard.region.currency_code.toUpperCase()}`
giftCard?.region ? (
formatAmountWithSymbol({
amount: giftCard.value,
currency: giftCard.region.currency_code,
})
) : (
<div className="flex items-center space-x-2">
<span>N / A</span>
<InfoTooltip content={"Region has been deleted"} />
</div>
)
) : (
<StatusIndicator title="None" variant="danger" />
)}
Expand Down
83 changes: 83 additions & 0 deletions src/domain/gift-cards/details/edit-gift-card-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useState } from "react"
import Button from "../../../components/fundamentals/button"
import Modal from "../../../components/molecules/modal"
import Select from "../../../components/molecules/select"

const EditGiftCardModal = ({
handleClose,
handleSave,
giftCard,
updating,
regions,
region,
}) => {
// const [code, setCode] = useState(giftCard.code)
const [selectedRegion, setSelectedRegion] = useState({
value: region.id,
label: region.name,
})

const onSubmit = (e) => {
e.preventDefault()
if (handleSave) {
handleSave({ region_id: selectedRegion.value })
}
}

const regionOptions = regions.map((r) => ({
label: r.name,
value: r.id,
}))

return (
<Modal handleClose={handleClose} isLargeModal={true}>
<form onSubmit={(e) => onSubmit(e)}>
<Modal.Body isLargeModal={true}>
<Modal.Header handleClose={handleClose}>
<span className="inter-xlarge-semibold">
Edit Gift Card Details
</span>
</Modal.Header>
<Modal.Content>
{/* TODO: Missing backend support for updating code
<InputField
label="Code"
name="code"
value={code}
onChange={({ currentTarget }) => setCode(currentTarget.value)}
className="mb-4"
/> */}
<Select
label="Region"
options={regionOptions}
value={selectedRegion}
onChange={setSelectedRegion}
/>
</Modal.Content>
<Modal.Footer>
<div className="w-full flex justify-end">
<Button
variant="ghost"
size="small"
onClick={handleClose}
className="mr-2"
>
Cancel
</Button>
<Button
loading={updating}
variant="primary"
className="min-w-[100px]"
size="small"
type="submit"
>
Save
</Button>
</div>
</Modal.Footer>
</Modal.Body>
</form>
</Modal>
)
}
export default EditGiftCardModal
152 changes: 152 additions & 0 deletions src/domain/gift-cards/details/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { RouteComponentProps } from "@reach/router"
import {
useAdminGiftCard,
useAdminRegions,
useAdminUpdateGiftCard,
} from "medusa-react"
import moment from "moment"
import React, { useState } from "react"
import Spinner from "../../../components/atoms/spinner"
import Badge from "../../../components/fundamentals/badge"
import DollarSignIcon from "../../../components/fundamentals/icons/dollar-sign-icon"
import EditIcon from "../../../components/fundamentals/icons/edit-icon"
import Breadcrumb from "../../../components/molecules/breadcrumb"
import StatusSelector from "../../../components/molecules/status-selector"
import BodyCard from "../../../components/organisms/body-card"
import useToaster from "../../../hooks/use-toaster"
import { getErrorMessage } from "../../../utils/error-messages"
import { formatAmountWithSymbol } from "../../../utils/prices"
import EditGiftCardModal from "./edit-gift-card-modal"
import UpdateBalanceModal from "./update-balance-modal"

type GiftCardDetailsProps = {
id: string
} & RouteComponentProps

const GiftCardDetails: React.FC<GiftCardDetailsProps> = ({ id }) => {
const { gift_card, isLoading } = useAdminGiftCard(id)
const { regions } = useAdminRegions()

const updateGiftCard = useAdminUpdateGiftCard(gift_card?.id)

const toaster = useToaster()

const [showUpdateBalance, setShowUpdateBalance] = useState(false)
const [showEdit, setShowEdit] = useState(false)

const actions = [
{
label: "Edit",
onClick: () => setShowEdit(true),
icon: <EditIcon size={20} />,
},
{
label: "Update balance",
onClick: () => setShowUpdateBalance(true),
icon: <DollarSignIcon size={20} />,
},
]

const handleUpdate = (data) => {
updateGiftCard.mutate(
{ ...data },
{
onSuccess: () => {
toaster("Succesfully updated Gift Card", "success")
setShowEdit(false)
setShowUpdateBalance(false)
},
onError: (err) => toaster(getErrorMessage(err), "error"),
}
)
}

return (
<div>
<Breadcrumb
currentPage={"Gift Card Details"}
previousBreadcrumb={"Gift Cards"}
previousRoute="/a/gift-cards"
/>
<BodyCard
className={"h-auto min-h-0 w-full"}
title={`${gift_card?.code}`}
subtitle={`Gift Card id: ${gift_card?.id}`}
status={
<StatusSelector
isDraft={!!gift_card?.is_disabled}
activeState={"Active"}
draftState={"Disabled"}
onChange={() =>
handleUpdate({ is_disabled: !gift_card?.is_disabled })
}
/>
}
actionables={actions}
>
{isLoading || !gift_card ? (
<div className="w-full pt-2xlarge flex items-center justify-center">
<Spinner size={"large"} variant={"secondary"} />
</div>
) : (
<div className="flex justify-between">
<div className="flex mt-6 space-x-6 divide-x">
<div className="flex flex-col">
<div className="inter-smaller-regular text-grey-50 mb-1">
Original amount
</div>
<div>
{formatAmountWithSymbol({
amount: gift_card?.value,
currency: gift_card?.region.currency_code,
})}
</div>
</div>
<div className="flex flex-col pl-6">
<div className="inter-smaller-regular text-grey-50 mb-1">
Balance
</div>
<div>
{formatAmountWithSymbol({
amount: gift_card?.balance,
currency: gift_card?.region.currency_code,
})}
</div>
</div>
<div className="flex flex-col pl-6">
<div className="inter-smaller-regular text-grey-50 mb-1">
Created
</div>
<div>{moment(gift_card?.created_at).format("DD MMM YYYY")}</div>
</div>
</div>
<div className="flex items-end">
<Badge variant="default">{gift_card?.region?.name}</Badge>
</div>
</div>
)}
</BodyCard>
{showUpdateBalance && (
<UpdateBalanceModal
giftCard={gift_card}
currencyCode={gift_card?.region?.currency_code}
handleClose={() => setShowUpdateBalance(false)}
handleSave={handleUpdate}
updating={updateGiftCard.isLoading}
/>
)}
{showEdit && (
<EditGiftCardModal
giftCard={gift_card}
handleClose={() => setShowUpdateBalance(false)}
handleSave={handleUpdate}
regions={regions}
region={gift_card?.region}
updating={updateGiftCard.isLoading}
/>
)}
</div>
)
}

export default GiftCardDetails
79 changes: 79 additions & 0 deletions src/domain/gift-cards/details/update-balance-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState } from "react"
import Tooltip from "../../../components/atoms/tooltip"
import Button from "../../../components/fundamentals/button"
import Modal from "../../../components/molecules/modal"
import CurrencyInput from "../../../components/organisms/currency-input"

const UpdateBalanceModal = ({
handleClose,
handleSave,
currencyCode,
giftCard,
updating,
}) => {
const [balance, setBalance] = useState(giftCard.balance)

const handleChange = (amount: number | undefined) => {
if (amount) {
setBalance(amount)
}
}

const onSubmit = () => {
if (balance > giftCard.value) {
return
}

if (handleSave) {
handleSave({ balance })
}
}

return (
<Modal handleClose={handleClose}>
<Modal.Body>
<Modal.Header handleClose={handleClose}>
<span className="inter-xlarge-semibold">Update Balance</span>
</Modal.Header>
<Modal.Content>
<CurrencyInput readOnly currentCurrency={currencyCode} size="small">
<CurrencyInput.AmountInput
amount={giftCard.balance}
label="Price"
onChange={handleChange}
/>
</CurrencyInput>
</Modal.Content>
<Modal.Footer>
<div className="w-full flex justify-end">
<Button
variant="ghost"
size="small"
onClick={handleClose}
className="mr-2"
>
Cancel
</Button>
<Button
loading={updating}
variant="primary"
className="min-w-[100px]"
size="small"
onClick={onSubmit}
disabled={balance > giftCard.value}
>
{balance > giftCard.value ? (
<Tooltip content="Balance is above original value">
Save
</Tooltip>
) : (
"Save"
)}
</Button>
</div>
</Modal.Footer>
</Modal.Body>
</Modal>
)
}
export default UpdateBalanceModal
7 changes: 4 additions & 3 deletions src/domain/gift-cards/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { Router } from "@reach/router"
import { navigate } from "gatsby"
import {
useAdminDeleteProduct,
useAdminGiftCards,
useAdminProducts,
useAdminUpdateProduct,
} from "medusa-react"
import React from "react"
import Overview from "./overview"
import useToaster from "../../hooks/use-toaster"
import { ProductStatus } from "../../types/shared"
import { getErrorMessage } from "../../utils/error-messages"
import GiftCardDetails from "./details"
import ManageGiftCard from "./manage"
import { ProductStatus } from "../../types/shared"
import Overview from "./overview"

const GiftCard = () => {
const { products: giftCards, isLoading } = useAdminProducts({
Expand Down Expand Up @@ -70,6 +70,7 @@ const GiftCard = () => {
onUpdate={() => updateGCStatus()}
isLoading={isLoading}
/>
<GiftCardDetails path=":id" />
{giftCard && (
<ManageGiftCard
path="manage"
Expand Down

0 comments on commit 12c04a8

Please sign in to comment.