Skip to content

Commit

Permalink
feat(console): Seat removal
Browse files Browse the repository at this point in the history
  • Loading branch information
Cosmin-Parvulescu committed Sep 27, 2023
1 parent 70d8ca7 commit ec58372
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 0 deletions.
213 changes: 213 additions & 0 deletions apps/console/app/components/Billing/seating.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Listbox, Transition } from '@headlessui/react'
import { Button } from '@proofzero/design-system'
import { Text } from '@proofzero/design-system/src/atoms/text/Text'
import { ToastWithLink } from '@proofzero/design-system/src/atoms/toast/ToastWithLink'
Expand All @@ -9,6 +10,9 @@ import classnames from 'classnames'
import { useState } from 'react'
import { FaTrash } from 'react-icons/fa'
import {
HiArrowNarrowRight,
HiChevronDown,
HiChevronUp,
HiMinus,
HiOutlineShoppingCart,
HiOutlineX,
Expand Down Expand Up @@ -183,20 +187,219 @@ export const PurchaseGroupSeatingModal = ({
)
}

export const RemoveGroupSeatingModal = ({
isOpen,
setIsOpen,
removalFn,
seatsUsed,
totalSeats,
paymentIsSetup,
}: {
isOpen: boolean
setIsOpen: (open: boolean) => void
removalFn: (quantity: number) => void
seatsUsed: number
totalSeats: number
paymentIsSetup: boolean
}) => {
const [seatsNew, setSeatsNew] = useState(seatsUsed)
return (
<Modal isOpen={isOpen} handleClose={() => setIsOpen(false)}>
<div className="max-sm:w-screen sm:min-w-[640px] lg:min-w-[764px] w-fit">
<div className="pb-2 pt-5 px-5 w-full flex flex-row items-center justify-between">
<Text size="lg" weight="semibold" className="text-left text-gray-800">
Remove Additional User Seat(s)
</Text>
<div
className={`bg-white p-2 rounded-lg text-xl cursor-pointer
hover:bg-[#F3F4F6]`}
onClick={() => {
setIsOpen(false)
}}
>
<HiOutlineX />
</div>
</div>
<section className="p-5 pt-auto w-full">
<div className="w-full border rounded-lg overflow-auto thin-scrollbar">
<div className="p-6">
<Text
size="lg"
weight="semibold"
className="text-gray-900 text-left"
>
Additional User Seats
</Text>
<ul className="pl-4">
<li className="list-disc text-sm font-medium text-gray-500 text-left">
You are currently using {seatsUsed}/{totalSeats} Additional
User Seats
</li>
<li className="list-disc text-sm font-medium text-gray-500 text-left">
You can remove some Members of your Group if you'd like to pay
for fewer Seats.
</li>
</ul>
</div>
<div className="border-b border-gray-200"></div>
<div className="p-6 flex justify-between items-center">
<div>
<Text
size="sm"
weight="medium"
className="text-gray-800 text-left"
>
Number of Additional Seats
</Text>
<Text
size="sm"
weight="medium"
className="text-gray-500 text-left"
>{`${totalSeats} x ${seatingCost}/month`}</Text>
</div>

<div className="flex flex-row text-gray-500 space-x-4">
<div className="flex flex-row items-center space-x-2">
<Text size="sm">{totalSeats} Entitlements</Text>
<HiArrowNarrowRight />
</div>

<div className="flex flex-row">
<Listbox
value={seatsNew}
onChange={setSeatsNew}
disabled={seatsUsed === totalSeats}
as="div"
>
{({ open }) => {
return (
<div>
<Listbox.Button
className="relative w-full cursor-default border
py-1.5 px-4 text-left sm:text-sm rounded-lg
focus:border-indigo-500 focus:outline-none focus:ring-1
flex flex-row space-x-3 items-center"
>
<Text size="sm">{seatsNew}</Text>
{open ? (
<HiChevronUp className="text-right" />
) : (
<HiChevronDown className="text-right" />
)}
</Listbox.Button>
<Transition
show={open}
as="div"
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
className="bg-gray-800"
>
<Listbox.Options
className="absolute no-scrollbar w-full bg-white
rounded-lg border max-h-[150px] max-w-[66.1833px] overflow-auto"
>
{Array.apply(null, Array(totalSeats + 1)).map(
(_, i) => {
return i >= seatsUsed ? (
<Listbox.Option
key={i}
value={i}
className="flex items-center
cursor-pointer hover:bg-gray-100
rounded-lg m-1"
>
{({ selected }) => {
return (
<div
className={`w-full h-full px-4 py-1.5
rounded-lg ${
selected ? 'bg-gray-100 font-medium' : ''
}`}
>
{i}
</div>
)
}}
</Listbox.Option>
) : null
}
)}
</Listbox.Options>
</Transition>
</div>
)
}}
</Listbox>
</div>
</div>
</div>
<div className="border-b border-gray-200"></div>

<div className="p-6 flex justify-between items-center">
<Text
size="sm"
weight="medium"
className="text-gray-800 text-left"
>
Changes to your subscription
</Text>

<div className="flex flex-row gap-2 items-center">
<Text size="lg" weight="semibold" className="text-gray-900">{`${
seatingCost * (totalSeats - seatsNew) !== 0 ? '-' : ''
}$${seatingCost * (totalSeats - seatsNew)}`}</Text>
<Text size="sm" weight="medium" className="text-gray-500">
per month
</Text>
</div>
</div>
</div>
</section>
<section className="flex flex-row-reverse gap-4 mt-auto m-5">
<Button
btnType="dangerous-alt"
disabled={
!paymentIsSetup ||
seatsUsed === totalSeats ||
seatsNew < seatsUsed ||
seatsNew === totalSeats
}
onClick={() => {
setIsOpen(false)
setSeatsNew(seatsNew)

removalFn(seatsNew)
}}
>
Remove Entitlement(s)
</Button>
<Button btnType="secondary-alt" onClick={() => setIsOpen(false)}>
Cancel
</Button>
</section>
</div>
</Modal>
)
}

export const GroupSeatingCard = ({
groupID,
seatsTotal,
seatsUsed,
paymentData,
purchaseFn,
removalFn,
}: {
groupID: string
seatsTotal: number
seatsUsed: number
paymentData?: PaymentData
purchaseFn: (quantity: number) => void
removalFn: (quantity: number) => void
}) => {
const [isPurchaseModalOpen, setIsPurchaseModalOpen] = useState(false)
const [isRemovalModalOpen, setIsRemovalModalOpen] = useState(false)

return (
<>
Expand All @@ -208,6 +411,15 @@ export const GroupSeatingCard = ({
purchaseFn={purchaseFn}
/>

<RemoveGroupSeatingModal
isOpen={isRemovalModalOpen}
setIsOpen={setIsRemovalModalOpen}
removalFn={removalFn}
seatsUsed={seatsUsed}
totalSeats={seatsTotal}
paymentIsSetup={Boolean(paymentData?.paymentMethodID)}
/>

<article className="bg-white rounded-lg border">
<header className="flex flex-col lg:flex-row justify-between lg:items-center p-4 relative">
<div>
Expand Down Expand Up @@ -308,6 +520,7 @@ export const GroupSeatingCard = ({
<button
type="button"
className="flex flex-row items-center gap-3.5 text-indigo-500 cursor-pointer rounded-b-lg disabled:text-indigo-300"
onClick={() => setIsRemovalModalOpen(true)}
>
<FaTrash className="w-3.5 h-3.5" />
<Text size="sm" weight="medium">
Expand Down
15 changes: 15 additions & 0 deletions apps/console/app/routes/__layout/billing/groups/$groupID.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,21 @@ export default () => {
}
)
}}
removalFn={(quantity) => {
submit(
{
payload: JSON.stringify({
quantity: quantity,
customerID: paymentData?.customerID,
txType: 'remove',
txTarget: TxTarget.GroupSeats,
}),
},
{
method: 'post',
}
)
}}
/>
)}
</section>
Expand Down

0 comments on commit ec58372

Please sign in to comment.