From a2722f6b40a04e025ed8c77eaca6df1ebe0f02dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Eren?= Date: Sat, 31 Aug 2024 01:06:08 +0300 Subject: [PATCH] feat: registration page (#46) * feat: Registration Page * feat: Register page * feat: new modal design & generate proof modal * fix: add box-shadow to modal --------- Co-authored-by: Chqrles --- client/src/App.tsx | 13 +- client/src/components/Button/index.tsx | 5 + .../components/GenerateProofModal/index.tsx | 33 +++++ client/src/components/Modal/Content.tsx | 76 +++++------ client/src/components/Modal/Overlay.tsx | 2 +- client/src/components/WalletSidebar/index.tsx | 2 +- client/src/pages/Register.tsx | 125 ++++++++++++++++++ client/src/pages/RegisterPage.tsx | 91 ------------- client/src/pages/Registration.tsx | 74 +++++++++++ client/src/theme/colors.ts | 1 + client/src/theme/components/icons.tsx | 36 +++++ client/src/theme/components/text.tsx | 6 +- 12 files changed, 323 insertions(+), 141 deletions(-) create mode 100644 client/src/components/GenerateProofModal/index.tsx create mode 100644 client/src/pages/Register.tsx delete mode 100644 client/src/pages/RegisterPage.tsx create mode 100644 client/src/pages/Registration.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index 8178d7e..ee3682b 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,7 +1,8 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom' import Layout from 'src/components/Layout' -import RegisterPage from './pages/RegisterPage' +import RegisterPage from './pages/Register' +import RegistrationPage from './pages/Registration' import SwapPage from './pages/Swap' import StarknetProvider from './providers/StarknetProvider' @@ -15,7 +16,15 @@ const router = createBrowserRouter([ ), }, { - path: '/register', + path: '/registration', + element: ( + + + + ), + }, + { + path: '/registration/register', element: ( diff --git a/client/src/components/Button/index.tsx b/client/src/components/Button/index.tsx index a6fcef3..2963f2d 100644 --- a/client/src/components/Button/index.tsx +++ b/client/src/components/Button/index.tsx @@ -1,12 +1,17 @@ import styled from 'styled-components' export const PrimaryButton = styled.button` + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; width: 100%; padding: 16px; background-color: ${({ theme }) => theme.accent1}; border: 0; border-radius: 12px; font-weight: 500; + text-decoration: none; cursor: pointer; &:disabled { diff --git a/client/src/components/GenerateProofModal/index.tsx b/client/src/components/GenerateProofModal/index.tsx new file mode 100644 index 0000000..c249c78 --- /dev/null +++ b/client/src/components/GenerateProofModal/index.tsx @@ -0,0 +1,33 @@ +import { ThemedText } from 'src/theme/components' +import { Logo } from 'src/theme/components/icons' + +import { Column } from '../Flex' +import Content from '../Modal/Content' +import Overlay from '../Modal/Overlay' +import Portal from '../Portal' + +function GenerateProofModalContent() { + return ( + + + + + + Snarkification of the elliptic curve... + + + This might take a while + + + ) +} + +export default function GenerateProofModal() { + return ( + + + + + + ) +} diff --git a/client/src/components/Modal/Content.tsx b/client/src/components/Modal/Content.tsx index 558c47b..e4a05c8 100644 --- a/client/src/components/Modal/Content.tsx +++ b/client/src/components/Modal/Content.tsx @@ -5,73 +5,57 @@ import { styled } from 'styled-components' import { Column, Row } from '../Flex' const StyledContent = styled.div` - border: 3px solid ${({ theme }) => theme.neutral1}; - padding: 80px 32px; - background: ${({ theme }) => theme.bg1}; - z-index: 1060; position: fixed; - width: 100%; - top: 0; - bottom: 0; + z-index: 1060; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); display: flex; flex-direction: column; justify-content: center; - - @media only screen and (min-width: ${({ theme }) => `${theme.breakpoint.xs}px`}) { - left: 50%; - top: 50%; - width: 386px; - transform: translate(-50%, -50%); - padding: 32px; - bottom: unset; - } + width: 100%; + max-width: 480px; + padding: 16px; + background: ${({ theme }) => theme.bg2}; + border: 1px solid ${({ theme }) => theme.border}; + border-radius: 20px; + box-shadow: 0px 4px 4px 4px rgba(0, 0, 0, 0.3), 0px 8px 12px 10px rgba(0, 0, 0, 0.15); ` const TitleContainer = styled(Row)` - position: absolute; width: 100%; - padding: 0 4px; - text-align: center; - top: 16px; - - & > div { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - width: 100%; - } +` - @media only screen and (min-width: ${({ theme }) => `${theme.breakpoint.xs}px`}) { - top: -32px; - text-align: left; - } +const Title = styled(ThemedText.HeadlineSmall)` + width: 100%; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; ` -const CloseContainer = styled.div` - position: absolute; - color: ${({ theme }) => theme.neutral1}; +const CloseContainer = styled.button` width: 28px; height: 28px; padding: 4px; + background: transparent; + color: ${({ theme }) => theme.neutral1}; + border: none; cursor: pointer; - border: 3px solid ${({ theme }) => theme.neutral1}; - top: -3px; - right: -3px; + transition: color 0.15s linear; & > svg { display: block; } &:hover { - background: ${({ theme }) => theme.neutral1}; - color: ${({ theme }) => theme.bg1}; + color: ${({ theme }) => theme.neutral2}; } ` interface ContentProps { children: React.ReactNode title: string - close: () => void + close?: () => void } export default function Content({ children, title, close }: ContentProps) { @@ -79,12 +63,14 @@ export default function Content({ children, title, close }: ContentProps) { - {title} - + {title} - - - + {close && ( + + + + )} + {children} diff --git a/client/src/components/Modal/Overlay.tsx b/client/src/components/Modal/Overlay.tsx index 4e6b4bf..8f5a2ea 100644 --- a/client/src/components/Modal/Overlay.tsx +++ b/client/src/components/Modal/Overlay.tsx @@ -15,7 +15,7 @@ const StyledOverlay = styled.div` ` interface OverlayProps { - onClick: () => void + onClick?: () => void } export default function Overlay({ onClick }: OverlayProps) { diff --git a/client/src/components/WalletSidebar/index.tsx b/client/src/components/WalletSidebar/index.tsx index 76ddf6e..342d7a7 100644 --- a/client/src/components/WalletSidebar/index.tsx +++ b/client/src/components/WalletSidebar/index.tsx @@ -88,7 +88,7 @@ export default function WalletSidebar({ onClose }: WalletSidebarProps) { - + Registration diff --git a/client/src/pages/Register.tsx b/client/src/pages/Register.tsx new file mode 100644 index 0000000..31c2391 --- /dev/null +++ b/client/src/pages/Register.tsx @@ -0,0 +1,125 @@ +import { useEffect, useState } from 'react' +import { PrimaryButton } from 'src/components/Button' +import { Column, Row } from 'src/components/Flex' +import GenerateProofModal from 'src/components/GenerateProofModal' +import { ThemedText } from 'src/theme/components' +import { LockClosed, LockOpen } from 'src/theme/components/icons' +import { styled, useTheme } from 'styled-components' + +const Layout = styled(Column)` + width: 100%; + margin: 0 auto; + justify-content: center; + flex: 1; +` + +const Content = styled(Column)` + max-width: 464px; + width: 100%; +` + +const Headline = styled(Row)` + width: 100%; + justify-content: space-between; + margin-bottom: ${({ theme }) => theme.grids.md}; +` + +const ContentCard = styled(Column)` + width: 100%; + border-radius: 12px; + overflow: hidden; +` + +const NoDataCard = styled(Column)` + width: 100%; + align-items: center; + justify-content: center; + padding: 32px 0; + background-color: ${({ theme }) => theme.bg3}; +` + +const RevtagCard = styled(Row)` + width: 100%; + justify-content: space-between; + padding: 24px 16px; + background-color: ${({ theme }) => theme.bg3}; +` + +const ProofCard = styled(Row)` + width: 100%; + justify-content: flex-end; + gap: 8px; + padding: 16px; + background-color: ${({ theme }) => theme.bg2}; +` + +export default function RegisterPage() { + const theme = useTheme() + const [revtag, setRevtag] = useState('') + const [generatingProof, setGeneratingProof] = useState(false) + const [proven, setProven] = useState(false) + + useEffect(() => { + if (generatingProof) { + setTimeout(() => { + setProven(true) + setGeneratingProof(false) + }, 5_000) + } + }, [generatingProof]) + + return ( + + + + Register + + + {!revtag && ( + <> + + + No data detected + + + + setRevtag('chqrlesjuzw')}> + Open sidebar + + + )} + + {revtag && ( + <> + + + Revtag: + {revtag} + + + + {proven ? ( + + ) : ( + + )} + + {proven ? ( + Proved + ) : ( + Unproved + )} + + + + !proven && setGeneratingProof(true)}> + {proven ? 'Complete registration' : 'Generate proof'} + + + )} + + + {generatingProof && } + + ) +} diff --git a/client/src/pages/RegisterPage.tsx b/client/src/pages/RegisterPage.tsx deleted file mode 100644 index 9b48191..0000000 --- a/client/src/pages/RegisterPage.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { useState } from 'react' -import { PrimaryButton } from 'src/components/Button' -import { Card } from 'src/components/Card' -import { Column, Row } from 'src/components/Flex' -import { ThemedText } from 'src/theme/components' -import { styled } from 'styled-components' - -const Layout = styled(Column)` - margin: 0 auto; - justify-content: center; - gap: 16px; - height: 100vh; -` -const RegistrationHeader = styled(Column)` - display: flex; - justify-content: space-between; - flex-direction: row; - width: 100%; -` - -const StatusCardGroup = styled(Row)` - width: 100%; - justify-content: space-between; -` - -const RegisterCard = styled(Card)` - width: 560px; -` - -export default function RegisterPage() { - const [displayRegister, setDisplayRegister] = useState(false) - - return ( - - {displayRegister ? ( - <> - - - setDisplayRegister(false)} style={{ cursor: 'pointer' }}> - Back - - New Registration -
-
- - - Use the ZKRamp browser assistant to generate proof a valid Revolut account. Submit the proof to complete - registration. - -
- - - Registration Proofs - - - - No Revolut account proofs found. Please follow instructions in the browser sidebar to generate proof of an - existing Revtag. - - - - Open Sidebar - - - - ) : ( - <> - Revolut Registration - - - You must register with a valid Revolut account to use ZKRamp. Your account details are hashed to conceal - your identity. - - - - - Status - - - Not Registered - - - setDisplayRegister(true)}> - + Register - - - - )} -
- ) -} diff --git a/client/src/pages/Registration.tsx b/client/src/pages/Registration.tsx new file mode 100644 index 0000000..deaddf9 --- /dev/null +++ b/client/src/pages/Registration.tsx @@ -0,0 +1,74 @@ +import { Link } from 'react-router-dom' +import { PrimaryButton } from 'src/components/Button' +import { Column, Row } from 'src/components/Flex' +import { ThemedText } from 'src/theme/components' +import { Empty, Plus } from 'src/theme/components/icons' +import { styled } from 'styled-components' + +const Layout = styled(Column)` + width: 100%; + margin: 0 auto; + justify-content: center; + flex: 1; +` + +const Content = styled(Column)` + max-width: 850px; + width: 100%; +` + +const Headline = styled(Row)` + width: 100%; + justify-content: space-between; + margin-bottom: ${({ theme }) => theme.grids.md}; +` + +const RegisterButton = styled(PrimaryButton)` + width: auto; + gap: 3px; + padding: 8px; + color: ${({ theme }) => theme.neutral1}; +` + +const ContentCard = styled(Column)` + width: 100%; + min-height: 220px; + padding: 20px 16px; + border: 1px solid ${({ theme }) => theme.border2}; + border-radius: 20px; +` + +const EmptyCard = styled(Column)` + flex: 1; + align-items: center; + justify-content: center; + gap: 8px; + color: ${({ theme }) => theme.neutral1}; +` + +export default function RegistrationPage() { + return ( + + + + Registration + + + + Register + + + + + + + + + Your registered accounts will appear here. + + + + + + ) +} diff --git a/client/src/theme/colors.ts b/client/src/theme/colors.ts index eeee35f..47d53c3 100644 --- a/client/src/theme/colors.ts +++ b/client/src/theme/colors.ts @@ -27,6 +27,7 @@ export const darkTheme = { surface: '#0D0D12', border: 'rgba(240, 247, 244, 0.1)', + border2: 'rgba(240, 247, 244, 0.5)', neutral1: colors.neutral1_dark, neutral2: colors.neutral2_dark, diff --git a/client/src/theme/components/icons.tsx b/client/src/theme/components/icons.tsx index 8ebcf9c..93f9ae0 100644 --- a/client/src/theme/components/icons.tsx +++ b/client/src/theme/components/icons.tsx @@ -113,3 +113,39 @@ export const Logout = (props: SVGProps) => ( /> ) + +export const Plus = (props: SVGProps) => ( + + + +) + +export const Empty = (props: SVGProps) => ( + + + +) + +export const LockOpen = (props: SVGProps) => ( + + + +) + +export const LockClosed = (props: SVGProps) => ( + + + +) diff --git a/client/src/theme/components/text.tsx b/client/src/theme/components/text.tsx index 5a5f752..8273ff7 100644 --- a/client/src/theme/components/text.tsx +++ b/client/src/theme/components/text.tsx @@ -36,7 +36,11 @@ export const ThemedText = { }, BodyPrimary(props: TextProps) { - return + return + }, + + BodySecondary(props: TextProps) { + return }, Title(props: TextProps) {