Skip to content

Commit

Permalink
Implement UI for certificate
Browse files Browse the repository at this point in the history
replacing privkey with privateKey

center components | adding unDraw illustration

creating 'loading' and 'certificate-display' components

creating new components for certificate
  • Loading branch information
Ririio committed Feb 17, 2023
1 parent fb7bf10 commit e6422fe
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 8 deletions.
111 changes: 111 additions & 0 deletions app/components/certificate/certificate-display.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import {
Flex,
Box,
HStack,
Text,
Heading,
Tooltip,
IconButton,
Accordion,
AccordionItem,
AccordionButton,
AccordionIcon,
AccordionPanel,
useToast,
} from '@chakra-ui/react';
import { DownloadIcon, CopyIcon } from '@chakra-ui/icons';
import type { Certificate } from '@prisma/client';

interface Props {
cert: Certificate;
priv: Boolean;
}

export default function CertificateDisplay(props: Props) {
const toast = useToast();

function onCopy() {
let key = props.cert.certificate;
let val = 'Public Key';

if (props.priv) {
key = props.cert.privateKey;
val = 'Private Key';
}

navigator.clipboard.writeText(key);
toast({
title: `${val} was copied to clipboard`,
position: 'bottom-right',
status: 'success',
});
}

return (
<Flex flexDirection="column" gap="5">
<Flex flexDirection="column" gap="4">
<HStack gap="4">
<Heading as="h4" size="sm">
{props.priv ? 'Private Key' : 'Public Key'}
</Heading>
<Tooltip label="Copy Public Key">
<IconButton
backgroundColor="transparent"
color="black"
size="xs"
_hover={{
background: 'whitesmoke',
color: 'teal.500',
}}
aria-label="Copy to Clipboard"
icon={<CopyIcon fontSize="md" />}
onClick={() => onCopy()}
/>
</Tooltip>
<Tooltip label="Download Public Key">
<IconButton
backgroundColor="transparent"
color="black"
size="xs"
_hover={{
background: 'brand.500',
color: 'white',
}}
aria-label="Download"
icon={
<DownloadIcon
fontSize="md"
onClick={() =>
toast({
title: props.priv ? 'Downloading Private Key' : 'Downloading Public Key',
position: 'bottom-right',
status: 'success',
})
}
/>
}
/>
</Tooltip>
</HStack>
<Text>
{props.priv
? " Private: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"
: " Public: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"}
</Text>
<Accordion allowMultiple>
<AccordionItem>
<AccordionButton>
<Box as="span" flex="1" textAlign="left">
Show/Hide
</Box>
<AccordionIcon />
</AccordionButton>
<AccordionPanel>
<Text>{props.priv ? props.cert.privateKey : props.cert.certificate}</Text>
</AccordionPanel>
</AccordionItem>
</Accordion>
</Flex>
</Flex>
);
}
36 changes: 36 additions & 0 deletions app/components/certificate/description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Flex, Heading, Text, HStack, VStack } from '@chakra-ui/react';
import type { Certificate } from '@prisma/client';

interface Props {
request: Boolean;
cert: Certificate;
}

export default function Description(props: Props) {
return (
<Flex flexDirection="column" gap="3" marginTop="14">
<Heading as="h1" size="xl">
Certificate
</Heading>
<Text>
{props.request
? "Certificate: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"
: "Initial: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"}
</Text>
{props.request ? (
<HStack gap="6" marginTop="2">
<VStack>
<Text fontWeight="bold">Created On</Text>
<Text>{props.cert.validFrom.toDateString()}</Text>
</VStack>
<VStack>
<Text fontWeight="bold">Expires On</Text>
<Text>{props.cert.validTo.toDateString()}</Text>
</VStack>
</HStack>
) : (
''
)}
</Flex>
);
}
18 changes: 18 additions & 0 deletions app/components/certificate/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Center, Flex, Box, Image, Heading } from '@chakra-ui/react';

import image from 'img/undraw_Processing_re_tbdu.png';

export default function Loading() {
return (
<Center paddingY="24">
<Flex flexDirection="column" width="5xl" textAlign="center" gap="5">
<Box>
<Image src={image} />
</Box>
<Heading as="h2" size="xl" fontFamily="heading" fontWeight="light" color="brand.500">
We have received your request, and will notify you when your certificate is ready
</Heading>
</Flex>
</Center>
);
}
21 changes: 21 additions & 0 deletions app/components/certificate/request.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Flex, Heading, Text, HStack } from '@chakra-ui/react';
import type { Certificate } from '@prisma/client';

interface Props {
cert: Certificate;
}

export default function Request(props: Props) {
return (
<Flex flexDirection="column" gap="1">
<Heading as="h3" size="md" marginBottom="3">
Domain Name
</Heading>
<Text>Lorem Ipsum is simply dummy text of the printing and typesetting industry</Text>

<HStack>
<Text fontWeight="bold">Domain Name:</Text> <Text>{props.cert.subject}</Text>
</HStack>
</Flex>
);
}
70 changes: 62 additions & 8 deletions app/routes/__index/certificate/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
import { Heading } from '@chakra-ui/react';
import { Flex, Center, Button, Divider } from '@chakra-ui/react';
import type { Certificate } from '@prisma/client';
import { useState } from 'react';

import Loading from '~/components/certificate/loading';
import CertificateDisplay from '~/components/certificate/certificate-display';
import Request from '~/components/certificate/request';
import Description from '~/components/certificate/description';

export default function CertificateIndexRoute() {
return (
<div>
<Heading as="h1" size="3xl">
Certificate Info or option to request a certificate
</Heading>
</div>
);
const [request, setRequest] = useState(false);
const [loading, setLoading] = useState(false);

function handleSubmit() {
setLoading(true);
setTimeout(() => {
setRequest(true);
setLoading(false);
}, 5000);
}

let curDate: Date = new Date(2023, 2);

const certificate: Certificate = {
id: 1,
username: 'user_test',
subject: `*.user_test.example.com`,
certificate:
'Public----BEGIN CERTIFICATE-----MIIFMjCCAxoCCQCVordquLnq8TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNzA5MTQxNDMzMTRaFw0xODA5MTQxNDMzMTRaMFsxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDASBgNVBAMTC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwi2PYBNGl1n78niRGDKgcsWK03TcTeVbQ1HztA57Rr1iDHAZNx3Mv4E/Sha8VKbKoshcmUcOS3AlmbIZX+7+9c7lL2oD+vtUZF1YUR/69fWuO72wk6fKj/eofxH9Ud5KFje8qrYZdJWKkPMdWlYgjD6qpA5wl60NiuxmUr44ADZDytqHzNThN3wrFruz74PcMfakcSUMxkh98LuNeGtqHpEAw+wliko3oDD4PanvDvp5mRgiQVKHEGT7dm85Up+W1iJKJ65fkc/j940MaLbdISZYYCT5dtPgCGKCHgVuVrY+OXFJrD3TTm94ILsR/BkS/VSKNigGVPXg3q8tgIS++k13CzLUO0PNRMuod1RD9j5NEc2CVic9rcH06ugZyHlOcuVvvRsPGd52BPn+Jf1aePKPPQHxT9i5GOs80CJw0eduZCDZB32biRYNwUtjFkHbu8ii2IGkvhnWonjd4w5wOldG+RPr+XoFCIaHp5TszQ+HnUTLIXKtBgzzCKjK4eZqrck7xpo5B5m5V7EUxBze2LYVky+GsDsqL8CggQqJL4ZKuZVoxgPwhnDy5nMs057NCU9EnXcauMW9UEqEHu5NXnmGJrCvQ56wjYN3lgvCHEtmIpsRjCCWaBJYiawu1J5ZAf1yGTVNh8pEvO//zL9ImUxrSfOGUeFiN1tzSFlTfbcCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAdZZpgWv79CgF5ny6HmMaYgsXJKJyQE9RhJ1cmzDY8KAF+nzT7q4Pgt3WbA9bpdji7C0WqKjX7hLipqhgFnqb8qZcodEKhX788qBj4X45+4nT6QipyJlz5x6KcCn/v9gQNKks7U+dBlqquiVfbXaa1EAKMeGtqinf+Y51nR/fBcr/P9TBnSJqH61KDO3qrE5KGTwHQ9VXoeKyeppGt5sYf8G0vwoHhtPTOO8TuLEIlFcXtzbC3zAtmQj6Su//fI5yjuYTkiayxMx8nCGrQhQSXdC8gYpYd0os7UY01DVu4BTCXEvf0GYXtiGJeG8lQT/eu7WdK83uJ93U/BMYzoq4lSVcqY4LNxlfAQXKhaAbioA5XyT7co7FQ0g+s2CGBUKa11wPDe8M2GVLPsxT2bXDQap5DQyVIuTwjtgL0tykGxPJPAnL2zuUy6T3/YzrWaJ9Os+6mUCVdLnXtDgZ10Ujel7mq6wo9Ns+u07grXZkXpmJYnJXBrwOsY8KZa5vFwgJrDXhWe+Fmgt1EP5VIqRCQAxH2iYvAaELi8udbN/ZiUU3K9t79MP/M3U/tEWAubHXsaAv03jRy43X0VjlZHmagU/4dU7RBWfyuwRarYIXLNT2FCd2z4kd3fsL3rB5iI+RH0uoNuOa1+UApfFCv0O65TYkp5jEWSlU8PhKYD43nXA=-----END CERTIFICATE-----',
orderUrl: `orderUrl.example.com`,
privateKey:
'Private----BEGIN CERTIFICATE-----MIIFMjCCAxoCCQCVordquLnq8TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNzA5MTQxNDMzMTRaFw0xODA5MTQxNDMzMTRaMFsxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDASBgNVBAMTC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwi2PYBNGl1n78niRGDKgcsWK03TcTeVbQ1HztA57Rr1iDHAZNx3Mv4E/Sha8VKbKoshcmUcOS3AlmbIZX+7+9c7lL2oD+vtUZF1YUR/69fWuO72wk6fKj/eofxH9Ud5KFje8qrYZdJWKkPMdWlYgjD6qpA5wl60NiuxmUr44ADZDytqHzNThN3wrFruz74PcMfakcSUMxkh98LuNeGtqHpEAw+wliko3oDD4PanvDvp5mRgiQVKHEGT7dm85Up+W1iJKJ65fkc/j940MaLbdISZYYCT5dtPgCGKCHgVuVrY+OXFJrD3TTm94ILsR/BkS/VSKNigGVPXg3q8tgIS++k13CzLUO0PNRMuod1RD9j5NEc2CVic9rcH06ugZyHlOcuVvvRsPGd52BPn+Jf1aePKPPQHxT9i5GOs80CJw0eduZCDZB32biRYNwUtjFkHbu8ii2IGkvhnWonjd4w5wOldG+RPr+XoFCIaHp5TszQ+HnUTLIXKtBgzzCKjK4eZqrck7xpo5B5m5V7EUxBze2LYVky+GsDsqL8CggQqJL4ZKuZVoxgPwhnDy5nMs057NCU9EnXcauMW9UEqEHu5NXnmGJrCvQ56wjYN3lgvCHEtmIpsRjCCWaBJYiawu1J5ZAf1yGTVNh8pEvO//zL9ImUxrSfOGUeFiN1tzSFlTfbcCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAdZZpgWv79CgF5ny6HmMaYgsXJKJyQE9RhJ1cmzDY8KAF+nzT7q4Pgt3WbA9bpdji7C0WqKjX7hLipqhgFnqb8qZcodEKhX788qBj4X45+4nT6QipyJlz5x6KcCn/v9gQNKks7U+dBlqquiVfbXaa1EAKMeGtqinf+Y51nR/fBcr/P9TBnSJqH61KDO3qrE5KGTwHQ9VXoeKyeppGt5sYf8G0vwoHhtPTOO8TuLEIlFcXtzbC3zAtmQj6Su//fI5yjuYTkiayxMx8nCGrQhQSXdC8gYpYd0os7UY01DVu4BTCXEvf0GYXtiGJeG8lQT/eu7WdK83uJ93U/BMYzoq4lSVcqY4LNxlfAQXKhaAbioA5XyT7co7FQ0g+s2CGBUKa11wPDe8M2GVLPsxT2bXDQap5DQyVIuTwjtgL0tykGxPJPAnL2zuUy6T3/YzrWaJ9Os+6mUCVdLnXtDgZ10Ujel7mq6wo9Ns+u07grXZkXpmJYnJXBrwOsY8KZa5vFwgJrDXhWe+Fmgt1EP5VIqRCQAxH2iYvAaELi8udbN/ZiUU3K9t79MP/M3U/tEWAubHXsaAv03jRy43X0VjlZHmagU/4dU7RBWfyuwRarYIXLNT2FCd2z4kd3fsL3rB5iI+RH0uoNuOa1+UApfFCv0O65TYkp5jEWSlU8PhKYD43nXA=-----END CERTIFICATE-----',
validFrom: curDate,
validTo: new Date(curDate.getFullYear(), curDate.getMonth() + 6),
};

if (loading) {
return <Loading />;
} else {
return (
<Center>
<Flex flexDirection="column" gap="5" width="4xl">
{request && (
<>
<Description request={true} cert={certificate} />
<Divider />
<CertificateDisplay cert={certificate} priv={false} />
<Divider />
<CertificateDisplay cert={certificate} priv={true} />
</>
)}
{!request && (
<Flex flexDirection="column" gap="5" width="4xl">
<Description request={false} cert={certificate} />
<Request cert={certificate} />
<Button width="3xs" shadow="xl" onClick={handleSubmit}>
Request a Certificate
</Button>
</Flex>
)}
</Flex>
</Center>
);
}
}
Binary file added img/undraw_Processing_re_tbdu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e6422fe

Please sign in to comment.