Skip to content

Commit

Permalink
Merge branch 'main' into feat--personal-secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
rohan-chaturvedi authored Nov 15, 2023
2 parents a1463a5 + b05173d commit 50cb75d
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 110 deletions.
60 changes: 42 additions & 18 deletions frontend/app/[team]/apps/[app]/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppType } from '@/apollo/graphql'
import { useContext, useEffect } from 'react'
import DeleteAppDialog from '@/components/apps/DeleteAppDialog'
import { organisationContext } from '@/contexts/organisationContext'
import { FaCube } from 'react-icons/fa'

export default function AppSettings({ params }: { params: { team: string; app: string } }) {
const { activeOrganisation: organisation } = useContext(organisationContext)
Expand All @@ -26,30 +27,53 @@ export default function AppSettings({ params }: { params: { team: string; app: s

const app = data?.apps[0] as AppType

const readableDate =
app &&
`${new Date(app.createdAt).toDateString()}, ${new Date(app.createdAt).toLocaleTimeString()}`

return (
<div className="h-screen w-full text-black dark:text-white flex flex-col gap-16 mt-6">
<div className="max-w-screen-lg mx-auto space-y-10 divide-y divide-neutral-500/40 p-8 w-full text-black dark:text-white mt-6">
<h1 className="text-3xl font-semibold">Settings</h1>
{app && (
<div className="flex w-full justify-between">
<span className="text-gray-500 uppercase tracking-widest font-semibold text-sm">
created
</span>
<span>{app.createdAt}</span>
<div className="space-y-6 py-4">
<div className="space-y-1">
<h2 className="text-2xl font-semibold">App</h2>
<p className="text-neutral-500">App name and information</p>
</div>
<div className="flex items-center gap-4">
<FaCube className="shrink-0 text-neutral-500" size={60} />
<div className="flex flex-col gap-1">
<span className="text-2xl font-medium">{app.name}</span>

<div className="flex items-center gap-4 text-neutral-500">
<div className="text-base ">Created</div>
<span>{readableDate}</span>
</div>
<span className="text-neutral-500 text-sm">{app.id}</span>
</div>
</div>
</div>
)}
<div className="flex items-center justify-between p-3 rounded-lg bg-red-200 dark:bg-red-400/10">
<div>
<h3 className="text-red-500 dark:text-red-800 font-semibold">Delete app</h3>
<p className="text-neutral-500">Permanently delete this app</p>
<div className="space-y-6 py-4">
<div className="space-y-1">
<h2 className="text-2xl font-semibold text-black dark:text-white">Danger Zone</h2>
<p className="text-neutral-500">These actions may result in permanent loss of data</p>
</div>
<div className="flex items-center justify-between p-3 rounded-lg ring-1 ring-inset ring-red-200 dark:ring-red-400/10">
<div>
<h3 className="text-red-500 dark:text-red-800 font-semibold">Delete App</h3>
<p className="text-neutral-500">Permanently delete this App</p>
</div>

{organisation && app && (
<DeleteAppDialog
appId={app.id}
appName={app.name}
teamName={params.team}
organisationId={organisation.id}
/>
)}
{organisation && app && (
<DeleteAppDialog
appId={app.id}
appName={app.name}
teamName={params.team}
organisationId={organisation.id}
/>
)}
</div>
</div>
</div>
)
Expand Down
15 changes: 2 additions & 13 deletions frontend/app/[team]/apps/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,8 @@ export default function AppsHome({ params }: { params: { team: string } }) {
</Link>
))}
{organisation && apps && (
<div className="bg-white/50 dark:bg-neutral-800 opacity-40 hover:opacity-100 transition-opacity ease-in-out shadow-lg rounded-xl p-8 flex flex-col gap-y-20">
<div className="mx-auto my-auto">
<NewAppDialog
buttonLabel={
<div className="w-full flex mx-auto my-auto items-center">
<FaPlus size="32" className="text-neutral-800 dark:text-neutral-300" />
</div>
}
buttonVariant="text"
organisation={organisation}
appCount={apps.length}
/>
</div>
<div className="bg-zinc-100 dark:bg-neutral-800 opacity-80 hover:opacity-100 transition-opacity ease-in-out shadow-lg rounded-xl flex flex-col gap-y-20 min-h-[252px]">
<NewAppDialog organisation={organisation} appCount={apps.length} />
</div>
)}
</div>
Expand Down
9 changes: 7 additions & 2 deletions frontend/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
--card-rgb: 180, 185, 188;
--card-border-rgb: 131, 134, 135;

--toastify-color-success: rgb(16 185 129)!important;
--toastify-color-success: rgb(16 185 129) !important;
}

@media (prefers-color-scheme: dark) {
Expand Down Expand Up @@ -89,6 +89,11 @@ body {
max-width: 100vw;
overflow-x: hidden;
}

::-ms-reveal {
display: none;
}

/*
body {
color: rgb(var(--foreground-rgb));
Expand All @@ -113,7 +118,7 @@ a {

@layer components {
input {
@apply p-2 focus:outline-none
@apply p-2 focus:outline-none;
}

input:not(.custom) {
Expand Down
11 changes: 8 additions & 3 deletions frontend/components/apps/DeleteAppDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function DeleteAppDialog(props: {
return (
<>
<div className="flex items-center justify-center">
<Button variant="outline" onClick={openModal}>
<Button variant="danger" onClick={openModal}>
<FaTrash /> Delete
</Button>
</div>
Expand Down Expand Up @@ -163,10 +163,15 @@ export default function DeleteAppDialog(props: {
</div>

<div className="mt-8 flex items-center w-full justify-between">
<Button variant="secondary" type="button" onClick={closeModal}>
<Button
variant="secondary"
type="button"
onClick={closeModal}
disabled={loading}
>
Cancel
</Button>
<Button type="submit" variant="primary">
<Button type="submit" variant="danger" isLoading={loading}>
Delete
</Button>
</div>
Expand Down
105 changes: 31 additions & 74 deletions frontend/components/apps/NewAppDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { copyToClipBoard } from '@/utils/clipboard'
import { Dialog, Switch, Transition } from '@headlessui/react'
import { useSession } from 'next-auth/react'
import { Fragment, ReactNode, useContext, useEffect, useState } from 'react'
import { FaCopy, FaExclamationTriangle, FaEye, FaEyeSlash, FaTimes } from 'react-icons/fa'
import { FaCopy, FaExclamationTriangle, FaEye, FaEyeSlash, FaPlus, FaTimes } from 'react-icons/fa'
import { toast } from 'react-toastify'
import { Button } from '../common/Button'
import { GetApps } from '@/graphql/queries/getApps.gql'
Expand Down Expand Up @@ -37,12 +37,7 @@ import {
const FREE_APP_LIMIT = 3
const PRO_APP_LIMIT = 10

export default function NewAppDialog(props: {
appCount: number
organisation: OrganisationType
buttonLabel?: ReactNode
buttonVariant?: string
}) {
export default function NewAppDialog(props: { appCount: number; organisation: OrganisationType }) {
const { organisation, appCount } = props
const [isOpen, setIsOpen] = useState<boolean>(false)
const [name, setName] = useState<string>('')
Expand All @@ -51,6 +46,8 @@ export default function NewAppDialog(props: {
const [appId, setAppId] = useState<string>('')
const [createStarters, setCreateStarters] = useState<boolean>(appCount === 0)
const [appSecret, setAppSecret] = useState<string>('')
const [appCreating, setAppCreating] = useState<boolean>(false)

const { data: session } = useSession()

const [createApp] = useMutation(CreateApplication)
Expand All @@ -62,11 +59,6 @@ export default function NewAppDialog(props: {

const IS_CLOUD_HOSTED = process.env.APP_HOST || process.env.NEXT_PUBLIC_APP_HOST

const DEFAULT_BUTTON = {
label: 'Create an app',
variant: 'primary',
}

const { keyring, setKeyring } = useContext(KeyringContext)

useEffect(() => {
Expand All @@ -89,19 +81,16 @@ export default function NewAppDialog(props: {
}

const closeModal = () => {
reset()
setIsOpen(false)
if (!appCreating) {
reset()
setIsOpen(false)
}
}

const openModal = () => {
setIsOpen(true)
}

const handleCopy = (val: string) => {
copyToClipBoard(val)
toast.info('Copied')
}

const validateKeyring = async (password: string) => {
return new Promise<OrganisationKeyring>(async (resolve, reject) => {
if (keyring) resolve(keyring)
Expand Down Expand Up @@ -332,6 +321,7 @@ export default function NewAppDialog(props: {

const handleCreateApp = async () => {
const APP_VERSION = 1
setAppCreating(true)

return new Promise<boolean>(async (resolve, reject) => {
setTimeout(async () => {
Expand Down Expand Up @@ -380,10 +370,11 @@ export default function NewAppDialog(props: {

setAppSecret(`pss:v${APP_VERSION}:${appToken}:${appKeyShares[0]}:${wrapKey}`)
setAppId(`phApp:v${APP_VERSION}:${appKeys.publicKey}`)

setAppCreating(false)
resolve(true)
closeModal()
} catch (error) {
setAppCreating(false)
reject(error)
}
}, 500)
Expand All @@ -392,10 +383,11 @@ export default function NewAppDialog(props: {

const handleSubmit = async (event: { preventDefault: () => void }) => {
event.preventDefault()

toast.promise(handleCreateApp, {
pending: 'Setting up your app',
success: 'App created!',
error: 'Something went wrong! Please check your sudo password and try again.',
error: 'Something went wrong!',
})
}

Expand Down Expand Up @@ -424,14 +416,15 @@ export default function NewAppDialog(props: {

return (
<>
<div className="flex items-center justify-center">
<Button
variant={props.buttonVariant || DEFAULT_BUTTON.variant}
type="button"
onClick={openModal}
>
{props.buttonLabel || DEFAULT_BUTTON.label}
</Button>
<div
className="flex items-center justify-center cursor-pointer w-full h-full group"
role="button"
onClick={openModal}
>
<div className="flex items-center text-lg gap-1 rounded-full bg-zinc-900 py-1 px-3 text-white group-hover:bg-zinc-700 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-1 dark:ring-inset dark:ring-emerald-400/20 dark:group-hover:bg-emerald-400/10 dark:group-hover:text-emerald-300 dark:group-hover:ring-emerald-300">
<FaPlus />
Create an App
</div>
</div>

<Transition appear show={isOpen} as={Fragment}>
Expand Down Expand Up @@ -473,8 +466,8 @@ export default function NewAppDialog(props: {
<form onSubmit={handleSubmit}>
<div className="mt-2 space-y-6 group">
<p className="text-sm text-gray-500">
Create a new app by entering an app name below. A new set of encryption
keys will be created to secure your app.
Create a new App by entering an App name below. Your App will be
initialized with 3 new environments.
</p>
<div className="flex flex-col justify-center">
<label
Expand Down Expand Up @@ -554,10 +547,15 @@ export default function NewAppDialog(props: {
</div>

<div className="mt-8 flex items-center w-full justify-between">
<Button variant="secondary" type="button" onClick={closeModal}>
<Button
variant="secondary"
type="button"
onClick={closeModal}
disabled={appCreating}
>
Cancel
</Button>
<Button type="submit" variant="primary">
<Button type="submit" variant="primary" isLoading={appCreating}>
Create
</Button>
</div>
Expand All @@ -580,47 +578,6 @@ export default function NewAppDialog(props: {
)}
</div>
)}
{complete() && (
<div className="w-full break-all space-y-8 mt-6">
<div className="bg-neutral-200 dark:bg-neutral-800 shadow-inner p-3 rounded-lg">
<div className="uppercase text-xs tracking-widest text-gray-500 w-full flex items-center justify-between pb-4">
app name
</div>
<code className="text-xs text-black dark:text-white">{name}</code>
</div>

<div className="bg-emerald-200/60 dark:bg-emerald-400/10 shadow-inner p-3 rounded-lg">
<div className="uppercase text-xs tracking-widest text-gray-500 w-full flex items-center justify-between pb-4">
app id
<Button variant="outline" onClick={() => handleCopy(appId)}>
Copy <FaCopy />
</Button>
</div>
<code className="text-xs text-emerald-500">{appId}</code>
</div>

<div className="bg-red-200 dark:bg-red-400/10 shadow-inner p-3 rounded-lg">
<div className="w-full flex items-center justify-between pb-4">
<span className="uppercase text-xs tracking-widest text-gray-500">
app secret
</span>
<div className="flex gap-4">
<div className="rounded-lg bg-orange-800/30 text-orange-500 p-2 flex items-center gap-4">
<FaExclamationTriangle />
<div className="text-2xs">
{"Copy this value. You won't see it again!"}
</div>
</div>

<Button variant="outline" onClick={() => handleCopy(appSecret)}>
<FaCopy /> Copy
</Button>
</div>
</div>
<code className="text-xs text-red-500">{appSecret}</code>
</div>
</div>
)}
</Dialog.Panel>
</Transition.Child>
</div>
Expand Down

0 comments on commit 50cb75d

Please sign in to comment.