Skip to content

Commit

Permalink
feat(platform): Cancel app data storage service (#2797)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cosmin-Parvulescu authored Jan 19, 2024
1 parent de1fe0b commit d7fb632
Show file tree
Hide file tree
Showing 56 changed files with 1,022 additions and 232 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
298 changes: 240 additions & 58 deletions apps/console/app/routes/apps/$clientId/storage.ostrich.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { useOutletContext, useSubmit, useTransition } from '@remix-run/react'
import { Text } from '@proofzero/design-system'
import { Form, useOutletContext, useTransition } from '@remix-run/react'
import { Button, Text } from '@proofzero/design-system'
import { DocumentationBadge } from '~/components/DocumentationBadge'
import { ReadOnlyInput } from '@proofzero/design-system/src/atoms/form/ReadOnlyInput'
import { ToastType, toast } from '@proofzero/design-system/src/atoms/toast'
import { getRollupReqFunctionErrorWrapper } from '@proofzero/utils/errors'
import { ActionFunction } from '@remix-run/cloudflare'
import createCoreClient from '@proofzero/platform-clients/core'
import { generateTraceContextHeaders } from '@proofzero/platform-middleware/trace'
import { getAuthzHeaderConditionallyFromToken } from '@proofzero/utils'
import { requireJWT } from '~/utilities/session.server'
import { BadRequestError, InternalServerError } from '@proofzero/errors'
import { InputToggle } from '@proofzero/design-system/src/atoms/form/InputToggle'
import classNames from 'classnames'
import { appDetailsProps } from '~/types'
import { ExternalAppDataPackageType } from '@proofzero/types/billing'
import {
HiOutlineShoppingCart,
HiOutlineTrash,
HiOutlineX,
} from 'react-icons/hi'
import { ExternalAppDataPackageStatus } from '@proofzero/platform.starbase/src/jsonrpc/validators/externalAppDataPackageDefinition'
import { Spinner } from '@proofzero/design-system/src/atoms/spinner/Spinner'
import { useState } from 'react'
import { Modal } from '@proofzero/design-system/src/molecules/modal/Modal'
import dangerVector from '~/images/danger.svg'
import { Input } from '@proofzero/design-system/src/atoms/form/Input'

export const action: ActionFunction = getRollupReqFunctionErrorWrapper(
async ({ request, context, params }) => {
Expand Down Expand Up @@ -54,72 +62,246 @@ export const action: ActionFunction = getRollupReqFunctionErrorWrapper(
}
)

export const ConfirmCancelModal = ({
isOpen,
setIsOpen,
}: {
isOpen: boolean
setIsOpen: (val: boolean) => void
}) => {
const [confirmationText, setConfirmationText] = useState('')
const transition = useTransition()

return (
<Modal isOpen={isOpen} handleClose={() => setIsOpen(false)}>
<div
className={`w-fit rounded-lg bg-white p-4
text-left transition-all sm:p-5 overflow-y-auto flex items-start space-x-4 max-w-[512px]`}
>
<img src={dangerVector} alt="danger" />

<div className="flex-1">
<div className="flex flex-row items-center justify-between w-full mb-2">
<Text size="lg" weight="medium" className="text-gray-900">
Cancel Service
</Text>
<button
className={`bg-white p-2 rounded-lg text-xl cursor-pointer
hover:bg-[#F3F4F6]`}
onClick={() => {
setIsOpen(false)
}}
>
<HiOutlineX />
</button>
</div>

<Form
method="post"
onSubmit={() => {
setConfirmationText('')
setIsOpen(false)
}}
>
<input type="hidden" name="op" value="disable" />
<section className="mb-4">
<Text size="sm" weight="normal" className="text-gray-500 my-3">
Are you sure you want to stop{' '}
<Text type="span" weight="semibold" size="sm">
App Data Storage?
</Text>
<br /> This action will permanently delete all data from the
service and any paid package used by the service will not be
renewed in next billing cycle.
</Text>

<Text size="sm" weight="normal" className="text-gray-500 my-3">
* Type CANCEL to confirm
</Text>

<Input
id="confirm_text"
placeholder="CANCEL"
value={confirmationText}
required
className="mb-12"
onChange={(e) => {
setConfirmationText(e.target.value)
}}
/>
</section>

<div className="flex justify-end items-center space-x-3">
<Button btnType="secondary-alt" onClick={() => setIsOpen(false)}>
Cancel
</Button>
<Button
disabled={
confirmationText !== 'CANCEL' || transition.state !== 'idle'
}
type="submit"
btnType="dangerous"
>
Delete
</Button>
</div>
</Form>
</div>
</div>
</Modal>
)
}

export default () => {
const { appDetails } = useOutletContext<{
appDetails: appDetailsProps
}>()

const trans = useTransition()
const submit = useSubmit()
const [isModalOpen, setIsModalOpen] = useState(false)

return (
<section className="flex flex-col space-y-5">
<div className="flex flex-row items-center space-x-3">
<Text size="2xl" weight="semibold" className="text-gray-900">
Storage
</Text>
<DocumentationBadge
url={'https://docs.rollup.id/platform/console/storage'}
/>
</div>
<>
{isModalOpen && (
<ConfirmCancelModal isOpen={isModalOpen} setIsOpen={setIsModalOpen} />
)}
<section className="flex flex-col space-y-5">
<div className="flex flex-row items-center space-x-3">
<Text size="2xl" weight="semibold" className="text-gray-900">
Storage
</Text>
<DocumentationBadge
url={'https://docs.rollup.id/platform/console/storage'}
/>
</div>

<section className="flex-1 bg-white border rounded-lg px-4 pt-3 pb-6">
<section className="flex flex-row justify-between items-center">
<div className="flex flex-row gap-2 items-center">
<Text size="lg" weight="semibold">
App Data Storage
{appDetails.externalAppDataPackageDefinition?.status ===
ExternalAppDataPackageStatus.Deleting && (
<section className="my-4 p-4 flex flex-row items-center gap-3 bg-orange-50">
<Spinner color="#F97316" size={20} margin="unset" weight="slim" />
<Text size="sm" weight="medium" className="text-orange-600">
Service cancellation in progress. Existing application data being
deleted...{' '}
</Text>
</section>
)}

<div
className={classNames('w-2 h-2 rounded-full', {
'bg-green-500': Boolean(
appDetails.externalAppDataPackageDefinition
),
'bg-gray-300': !Boolean(
appDetails.externalAppDataPackageDefinition
),
})}
></div>
</div>
<section className="flex-1 bg-white border rounded-lg px-4 pt-3 pb-6">
<section className="flex flex-row justify-between items-center">
<div className="flex flex-row gap-2 items-center">
<Text size="lg" weight="semibold">
App Data Storage
</Text>

<InputToggle
id="toggle_storage"
checked={Boolean(appDetails.externalAppDataPackageDefinition)}
onToggle={() => {
submit(
{
op: Boolean(appDetails.externalAppDataPackageDefinition)
? 'disable'
: 'enable',
},
{
method: 'post',
}
)
}}
disabled={trans.state !== 'idle'}
/>
</section>
{appDetails.externalAppDataPackageDefinition?.status ===
ExternalAppDataPackageStatus.Deleting ? (
<div className="w-2 h-2 rounded-full bg-orange-500"></div>
) : (
<div
className={classNames('w-2 h-2 rounded-full', {
'bg-green-500': Boolean(
appDetails.externalAppDataPackageDefinition
),
'bg-gray-300': !Boolean(
appDetails.externalAppDataPackageDefinition
),
})}
></div>
)}
</div>

<section className="mt-2">
<Text size="sm" className="text-gray-600">
App Data Storage service provides a hassle-free way to store and
retrieve per-user data for your application. Once activated, the
service can be accessed through our Galaxy API and it supports
storing data up to 128kb, per user.
</Text>
{appDetails.externalAppDataPackageDefinition?.status !==
ExternalAppDataPackageStatus.Deleting && (
<>
{!Boolean(appDetails.externalAppDataPackageDefinition) && (
<Form method="post">
<input type="hidden" name="op" value="enable" />
<Button
btnType="primary-alt"
className="flex flex-row items-center gap-3"
type="submit"
>
<HiOutlineShoppingCart className="w-3.5 h-3.5" />
<Text>Purchase Package</Text>
</Button>
</Form>
)}
{Boolean(appDetails.externalAppDataPackageDefinition) && (
<Button
btnType="dangerous-alt"
className="flex flex-row items-center gap-3"
type="submit"
onClick={() => {
setIsModalOpen(true)
}}
>
<HiOutlineTrash className="w-3.5 h-3.5" />
<Text>Cancel Service</Text>
</Button>
)}
</>
)}
</section>

<section className="mt-2">
<Text size="sm" className="text-gray-600">
App Data Storage service provides a hassle-free way to store and
retrieve per-user data for your application. <br /> Once
activated, the service can be accessed through our Galaxy API and
it supports storing data up to 128kb, per user.
</Text>
</section>
<section className="mt-4">
<div className="w-full h-px bg-gray-200"></div>
<div className="flex flex-row justify-between items-center py-2">
<Text size="sm" className="text-gray-800">
Current Package:
</Text>
<Text size="sm" className="text-gray-500">
{appDetails.externalAppDataPackageDefinition?.packageDetails
.title ?? 'No active package'}
</Text>
</div>
<div className="w-full h-px bg-gray-200"></div>
<div className="flex flex-row justify-between items-center py-2">
<Text size="sm" className="text-gray-800">
Reads:
</Text>
{Boolean(appDetails.externalAppDataPackageDefinition) ? (
<Text size="sm" className="text-gray-500">
{
appDetails.externalAppDataPackageDefinition?.packageDetails
.reads
}{' '}
/ month
</Text>
) : (
<Text size="sm" className="text-gray-500">
-
</Text>
)}
</div>
<div className="w-full h-px bg-gray-200"></div>
<div className="flex flex-row justify-between items-center pt-2">
<Text size="sm" className="text-gray-800">
Writes:
</Text>
{Boolean(appDetails.externalAppDataPackageDefinition) ? (
<Text size="sm" className="text-gray-500">
{
appDetails.externalAppDataPackageDefinition?.packageDetails
.writes
}{' '}
/ month
</Text>
) : (
<Text size="sm" className="text-gray-500">
-
</Text>
)}
</div>
</section>
</section>
</section>
</section>
</>
)
}
4 changes: 2 additions & 2 deletions apps/console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
},
"devDependencies": {
"@babel/core": "7.20.2",
"@cloudflare/workers-types": "4.20221111.1",
"@cloudflare/workers-types": "4.20231121.0",
"@mdx-js/react": "2.1.5",
"@playwright/test": "1.35.1",
"@proofzero/platform.starbase": "workspace:*",
Expand All @@ -79,7 +79,7 @@
"npm-run-all": "4.1.5",
"tailwindcss": "3.3.3",
"typescript": "5.0.4",
"wrangler": "3.2.0"
"wrangler": "3.18"
},
"engines": {
"node": ">=16.13"
Expand Down
4 changes: 2 additions & 2 deletions apps/passport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
},
"devDependencies": {
"@babel/core": "^7.20.2",
"@cloudflare/workers-types": "4.20221111.1",
"@cloudflare/workers-types": "4.20231121.0",
"@mdx-js/react": "^1.6.22",
"@playwright/test": "1.35.1",
"@remix-run/dev": "1.14.0",
Expand Down Expand Up @@ -106,7 +106,7 @@
"tailwindcss": "3.3.3",
"typescript": "5.0.4",
"webpack": "5.75.0",
"wrangler": "3.2.0"
"wrangler": "3.18"
},
"engines": {
"node": ">=16.13"
Expand Down
4 changes: 2 additions & 2 deletions apps/profile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"devDependencies": {
"@babel/core": "7.20.2",
"@cloudflare/workers-types": "4.20221111.1",
"@cloudflare/workers-types": "4.20231121.0",
"@mdx-js/react": "2.1.5",
"@playwright/test": "1.35.1",
"@remix-run/dev": "1.14.0",
Expand Down Expand Up @@ -111,7 +111,7 @@
"tailwindcss": "3.3.3",
"typescript": "5.0.4",
"webpack": "5.75.0",
"wrangler": "3.2.0"
"wrangler": "3.18"
},
"engines": {
"node": ">=16.13"
Expand Down
Loading

0 comments on commit d7fb632

Please sign in to comment.