From 3535bd3a588dc2281bc6a94fb89e5c731003f0d7 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 10:53:05 +0700 Subject: [PATCH 01/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20GitTeaIcon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/CustomIcon/GitTeaIcon.tsx | 27 +++++++++++++++++++ .../src/components/shared/CustomIcon/index.ts | 1 + 2 files changed, 28 insertions(+) create mode 100644 packages/frontend/src/components/shared/CustomIcon/GitTeaIcon.tsx diff --git a/packages/frontend/src/components/shared/CustomIcon/GitTeaIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/GitTeaIcon.tsx new file mode 100644 index 00000000..6131822a --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/GitTeaIcon.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const GitTeaIcon: React.FC = (props) => { + return ( + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 5de3702d..057c3e4e 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -23,6 +23,7 @@ export * from './EllipsesIcon'; export * from './SnowballIcon'; export * from './NotificationBellIcon'; export * from './GithubIcon'; +export * from './GitTeaIcon'; export * from './LockIcon'; export * from './PencilIcon'; export * from './CheckRadioIcon'; From 3b67396c433cac7158e56d8ae9a7d99acb7add55 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 10:55:10 +0700 Subject: [PATCH 02/13] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20reskin=20con?= =?UTF-8?q?nect=20github?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/create/ConnectAccount.tsx | 75 ++++++++++++------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index 084cd23b..e09d3dab 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -7,6 +7,8 @@ import { GitIcon, EllipsesIcon, SnowballIcon, + GithubIcon, + GitTeaIcon, } from 'components/shared/CustomIcon'; const SCOPES = 'repo user'; @@ -34,36 +36,55 @@ const ConnectAccount: React.FC = ({ // TODO: Use correct height return (
-
-
- +
+ {/** Icons */} +
+
+
+ +
+ +
+
+ +
- -
- + {/** Text */} +
+

+ Connect to your Git account +

+

+ Once connected, you can import a repository from your account or + start with one of our templates. +

-
-
-
- Connect to your Git account + {/** CTA Buttons */} +
+ {}} + title="Snowball" + width={1000} + height={1000} + > + + +
-
- Once connected, you can import a repository from your account or start - with one of our templates. -
-
-
- {}} - title="Snowball" - width={1000} - height={1000} - > - - -
{/* TODO: Add ConnectAccountTabPanel */} From 89306ddcc727210e6736f12250487004c96425ce Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 11:19:09 +0700 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20toast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/projects/create/ConnectAccount.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index e09d3dab..2882ef9c 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -10,6 +10,7 @@ import { GithubIcon, GitTeaIcon, } from 'components/shared/CustomIcon'; +import { useToast } from 'components/shared/Toast'; const SCOPES = 'repo user'; const GITHUB_OAUTH_URL = `https://github.com/login/oauth/authorize?client_id=${ @@ -25,12 +26,20 @@ const ConnectAccount: React.FC = ({ }: ConnectAccountInterface) => { const client = useGQLClient(); + const { toast, dismiss } = useToast(); + const handleCode = async (code: string) => { // Pass code to backend and get access token const { authenticateGitHub: { token }, } = await client.authenticateGitHub(code); onToken(token); + toast({ + onDismiss: dismiss, + id: 'connected-to-github', + title: 'The Git account is connected.', + variant: 'success', + }); }; // TODO: Use correct height From 2585418ed62e3f77322927dddb74dd8b4b5b5336 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 13:39:30 +0700 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20implement=20IconW?= =?UTF-8?q?ithFrame=20common=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/IconWithFrame/IconWithFrame.tsx | 32 +++++++++++++++++++ .../components/shared/IconWithFrame/index.ts | 1 + 2 files changed, 33 insertions(+) create mode 100644 packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx create mode 100644 packages/frontend/src/components/shared/IconWithFrame/index.ts diff --git a/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx b/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx new file mode 100644 index 00000000..ab3f6a9a --- /dev/null +++ b/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx @@ -0,0 +1,32 @@ +import React, { ReactNode } from 'react'; +import { cn } from 'utils/classnames'; + +interface IconWithFrameProps { + icon: ReactNode; + bgClass?: string; + hasHighlight?: boolean; +} + +export const IconWithFrame = ({ + icon, + bgClass = 'bg-controls-secondary ', + hasHighlight = true, +}: IconWithFrameProps) => { + return ( +
+ {hasHighlight && ( +
+ )} + {icon} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/IconWithFrame/index.ts b/packages/frontend/src/components/shared/IconWithFrame/index.ts new file mode 100644 index 00000000..a7d3a98e --- /dev/null +++ b/packages/frontend/src/components/shared/IconWithFrame/index.ts @@ -0,0 +1 @@ +export * from './IconWithFrame'; From c5273ff530ca21317a85104323c8735b24c17cc5 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 13:39:50 +0700 Subject: [PATCH 05/13] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20use=20Ic?= =?UTF-8?q?onWithFrame?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/projects/create/ConnectAccount.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index 2882ef9c..eede598a 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -11,6 +11,7 @@ import { GitTeaIcon, } from 'components/shared/CustomIcon'; import { useToast } from 'components/shared/Toast'; +import { IconWithFrame } from 'components/shared/IconWithFrame'; const SCOPES = 'repo user'; const GITHUB_OAUTH_URL = `https://github.com/login/oauth/authorize?client_id=${ @@ -48,15 +49,9 @@ const ConnectAccount: React.FC = ({
{/** Icons */}
-
-
- -
+ } /> -
-
- -
+ } />
{/** Text */}
From 319822c8e62ef060a35218f9b1102a35a54c7335 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 13:46:09 +0700 Subject: [PATCH 06/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20shadow=20to?= =?UTF-8?q?=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/projects/create/ConnectAccount.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index eede598a..fce56015 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -74,7 +74,7 @@ const ConnectAccount: React.FC = ({ height={1000} >
{/** Text */}
-

+ Connect to your Git account -

+

Once connected, you can import a repository from your account or start with one of our templates. From 3493d735b94b04e8114fa4365bfefb752e15c28c Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 14:19:02 +0700 Subject: [PATCH 09/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20replace=20bgClass?= =?UTF-8?q?=20with=20className?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/projects/create/ConnectAccount.tsx | 6 +++--- .../components/shared/IconWithFrame/IconWithFrame.tsx | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index 3d550867..6b38deb4 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -52,11 +52,11 @@ const ConnectAccount: React.FC = ({

} /> - } /> + } />
{/** Text */}
- + Connect to your Git account

@@ -65,7 +65,7 @@ const ConnectAccount: React.FC = ({

{/** CTA Buttons */} -
+
{ return ( @@ -18,9 +18,8 @@ export const IconWithFrame = ({ 'relative justify-center items-center gap-2.5 inline-flex', 'w-16 h-16 rounded-2xl shadow-inner', 'border border-b-[3px] border-border-interactive border-opacity-10', - { - [bgClass]: true, - }, + 'bg-controls-secondary', + className, )} > {hasHighlight && ( From 4a87c100d67cf67944248b76c6673a43e5038865 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 14:20:12 +0700 Subject: [PATCH 10/13] =?UTF-8?q?=F0=9F=94=A7=20chore:=20use=20proper=20ty?= =?UTF-8?q?pe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/IconWithFrame/IconWithFrame.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx b/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx index 10eba40c..77bea57a 100644 --- a/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx +++ b/packages/frontend/src/components/shared/IconWithFrame/IconWithFrame.tsx @@ -1,9 +1,8 @@ -import React, { ReactNode } from 'react'; +import React, { ComponentPropsWithoutRef, ReactNode } from 'react'; import { cn } from 'utils/classnames'; -interface IconWithFrameProps { +interface IconWithFrameProps extends ComponentPropsWithoutRef<'div'> { icon: ReactNode; - className?: string; hasHighlight?: boolean; } @@ -11,6 +10,7 @@ export const IconWithFrame = ({ icon, className, hasHighlight = true, + ...props }: IconWithFrameProps) => { return (
{hasHighlight && (
From bd4a51c830c7de8aafd29220a5fa358f4a908d2e Mon Sep 17 00:00:00 2001 From: Zachery Ng Date: Wed, 28 Feb 2024 15:45:57 +0800 Subject: [PATCH 11/13] style: update tertiary button --- .../src/components/projects/create/ConnectAccount.tsx | 4 ++-- .../src/components/shared/Button/Button.theme.ts | 11 ++++------- packages/frontend/tailwind.config.js | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/frontend/src/components/projects/create/ConnectAccount.tsx b/packages/frontend/src/components/projects/create/ConnectAccount.tsx index 6b38deb4..1fc099a2 100644 --- a/packages/frontend/src/components/projects/create/ConnectAccount.tsx +++ b/packages/frontend/src/components/projects/create/ConnectAccount.tsx @@ -75,7 +75,7 @@ const ConnectAccount: React.FC = ({ height={1000} >
{/* Wave */} - + {/* Lower content */}
{/* Latest deployment */} diff --git a/packages/frontend/src/components/projects/create/TemplateCard.tsx b/packages/frontend/src/components/projects/create/TemplateCard.tsx deleted file mode 100644 index 3625b64b..00000000 --- a/packages/frontend/src/components/projects/create/TemplateCard.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import toast from 'react-hot-toast'; - -import { IconButton, Typography } from '@material-tailwind/react'; - -import { Link } from 'react-router-dom'; - -interface TemplateDetails { - id: string; - name: string; - icon: string; -} -interface TemplateCardProps { - template: TemplateDetails; - isGitAuth: boolean; -} - -const CardDetails = ({ template }: { template: TemplateDetails }) => { - return ( -
- - {template.icon} {template.name} - -
- - {'>'} - -
-
- ); -}; - -const TemplateCard: React.FC = ({ template, isGitAuth }) => { - return isGitAuth ? ( - - - - ) : ( - - toast.error('Connect Git account to start with a template') - } - > - - - ); -}; - -export default TemplateCard; diff --git a/packages/frontend/src/components/projects/create/TemplateCard/TemplateCard.tsx b/packages/frontend/src/components/projects/create/TemplateCard/TemplateCard.tsx new file mode 100644 index 00000000..b7c549fd --- /dev/null +++ b/packages/frontend/src/components/projects/create/TemplateCard/TemplateCard.tsx @@ -0,0 +1,85 @@ +import { Button } from 'components/shared/Button'; +import { + ArrowRightCircleIcon, + ClockOutlineIcon, + TemplateIcon, + TemplateIconType, +} from 'components/shared/CustomIcon'; +import { Tag } from 'components/shared/Tag'; +import React, { ComponentPropsWithoutRef, useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useToast } from 'components/shared/Toast'; +import { cn } from 'utils/classnames'; + +export interface TemplateDetail { + id: string; + name: string; + icon: string; + repoFullName?: string; + isComingSoon?: boolean; +} + +export interface TemplateCardProps extends ComponentPropsWithoutRef<'div'> { + template: TemplateDetail; + isGitAuth: boolean; +} + +export const TemplateCard = ({ template, isGitAuth }: TemplateCardProps) => { + const { toast, dismiss } = useToast(); + const navigate = useNavigate(); + + const handleClick = useCallback(() => { + if (template?.isComingSoon) { + return toast({ + id: 'coming-soon', + title: 'This template is coming soon', + variant: 'info', + onDismiss: dismiss, + }); + } + if (isGitAuth) { + return navigate(`/template?templateId=${template.id}`); + } + return toast({ + id: 'connect-git-account', + title: 'Connect Git account to start with a template', + variant: 'error', + onDismiss: dismiss, + }); + }, [isGitAuth, navigate, template, toast]); + + return ( + + )} + + ); +}; diff --git a/packages/frontend/src/components/projects/create/TemplateCard/index.ts b/packages/frontend/src/components/projects/create/TemplateCard/index.ts new file mode 100644 index 00000000..55250834 --- /dev/null +++ b/packages/frontend/src/components/projects/create/TemplateCard/index.ts @@ -0,0 +1 @@ +export * from './TemplateCard'; diff --git a/packages/frontend/src/components/shared/Button/Button.theme.ts b/packages/frontend/src/components/shared/Button/Button.theme.ts index 5d5ba72e..262cb8f9 100644 --- a/packages/frontend/src/components/shared/Button/Button.theme.ts +++ b/packages/frontend/src/components/shared/Button/Button.theme.ts @@ -150,7 +150,7 @@ export const buttonTheme = tv( { size: 'md', iconOnly: true, - class: ['py-3.25', 'px-3.25'], + class: ['py-3', 'px-3'], }, { size: 'sm', diff --git a/packages/frontend/src/components/shared/CustomIcon/ArrowRightCircleIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/ArrowRightCircleIcon.tsx new file mode 100644 index 00000000..cce7cc58 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/ArrowRightCircleIcon.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const ArrowRightCircleIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/ClockOutlineIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/ClockOutlineIcon.tsx new file mode 100644 index 00000000..01fec9ba --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/ClockOutlineIcon.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const ClockOutlineIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 72205c83..754404be 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -33,4 +33,9 @@ export * from './GitHubLogo'; export * from './ClockIcon'; export * from './HorizontalDotIcon'; export * from './WarningDiamondIcon'; +export * from './ArrowRightCircleIcon'; +export * from './ClockOutlineIcon'; export * from './ArrowRightCircleFilledIcon'; + +// Templates +export * from './templates'; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/KotlinIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/KotlinIcon.tsx new file mode 100644 index 00000000..973b5f4f --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/KotlinIcon.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from '../CustomIcon'; + +export const KotlinIcon = (props: CustomIconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/PWAIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/PWAIcon.tsx new file mode 100644 index 00000000..f0edb351 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/PWAIcon.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from '../CustomIcon'; + +export const PWAIcon = (props: CustomIconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/ReactNativeIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/ReactNativeIcon.tsx new file mode 100644 index 00000000..bc170f98 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/ReactNativeIcon.tsx @@ -0,0 +1,98 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from '../CustomIcon'; + +export const ReactNativeIcon = (props: CustomIconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/SwiftIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/SwiftIcon.tsx new file mode 100644 index 00000000..d3422dff --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/SwiftIcon.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from '../CustomIcon'; + +export const SwitfIcon = (props: CustomIconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/TemplateIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/TemplateIcon.tsx new file mode 100644 index 00000000..c7b307bb --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/TemplateIcon.tsx @@ -0,0 +1,42 @@ +import React, { useMemo } from 'react'; +import { CustomIconProps } from '../CustomIcon'; +import { ReactNativeIcon } from './ReactNativeIcon'; +import { cloneIcon } from 'utils/cloneIcon'; +import { PWAIcon } from './PWAIcon'; +import { WebAppIcon } from './WebAppIcon'; +import { KotlinIcon } from './KotlinIcon'; +import { SwitfIcon } from './SwiftIcon'; + +const TEMPLATE_ICONS = [ + 'react-native', + 'pwa', + 'web', + 'kotlin', + 'swift', +] as const; +export type TemplateIconType = (typeof TEMPLATE_ICONS)[number]; + +export interface TemplateIconProps extends CustomIconProps { + type: TemplateIconType; +} + +export const TemplateIcon = ({ type, ...props }: TemplateIconProps) => { + const renderIcon = useMemo(() => { + switch (type) { + case 'react-native': + return ; + case 'pwa': + return ; + case 'web': + return ; + case 'kotlin': + return ; + case 'swift': + return ; + default: + throw new Error(`Invalid template icon type: ${type}`); + } + }, [type]); + + return cloneIcon(renderIcon, props) as JSX.Element; +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/WebAppIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/templates/WebAppIcon.tsx new file mode 100644 index 00000000..f707fccc --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/WebAppIcon.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from '../CustomIcon'; + +export const WebAppIcon = (props: CustomIconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/templates/index.ts b/packages/frontend/src/components/shared/CustomIcon/templates/index.ts new file mode 100644 index 00000000..e2879355 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/templates/index.ts @@ -0,0 +1 @@ +export * from './TemplateIcon'; diff --git a/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx b/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx index 0d746749..c60ab4d3 100644 --- a/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx +++ b/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx @@ -43,7 +43,7 @@ export const Sidebar = () => { }, [disconnect, navigate]); return ( -
+
+ ); }; diff --git a/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx b/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx index 45bc7234..805272f1 100644 --- a/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx +++ b/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx @@ -1,16 +1,44 @@ -import React, { ComponentPropsWithoutRef } from 'react'; +import React, { ComponentPropsWithoutRef, useMemo } from 'react'; import { cn } from 'utils/classnames'; -export interface WavyBorderProps extends ComponentPropsWithoutRef<'div'> {} +type WaveBorderVariant = 'stroke' | 'stroke-and-fill'; + +export interface WavyBorderProps extends ComponentPropsWithoutRef<'div'> { + variant?: WaveBorderVariant; +} export const WavyBorder = ({ className, - children, + variant = 'stroke', ...props }: WavyBorderProps) => { + const imageSrc = useMemo(() => { + switch (variant) { + case 'stroke-and-fill': + return '/wavy-border-line-and-fill.svg'; + case 'stroke': + default: + return '/wavy-border-line.svg'; + } + }, [variant]); + return ( -
- {children} +
+ {/* Wave */} +
); }; diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index 60291de7..502904a5 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -153,12 +153,4 @@ .focus-ring { @apply focus-visible:ring-[3px] focus-visible:ring-snowball-200 focus-visible:ring-offset-1 focus-visible:ring-offset-snowball-500 focus-visible:outline-none; } - - .wave { - background-image: url('../public/wave-border.svg'); - background-repeat: repeat-x; - background-position: top; - background-size: cover; - @apply w-full h-1; - } } diff --git a/packages/frontend/src/pages/OrgSlug.tsx b/packages/frontend/src/pages/OrgSlug.tsx deleted file mode 100644 index 834bb15d..00000000 --- a/packages/frontend/src/pages/OrgSlug.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { Outlet } from 'react-router-dom'; - -import { OctokitProvider } from 'context/OctokitContext'; -import { Sidebar } from 'components/shared/Sidebar'; - -const OrgSlug = () => { - return ( -
- <> -
- -
-
-
- - - -
-
- -
- ); -}; - -export default OrgSlug; diff --git a/packages/frontend/src/pages/org-slug/layout.tsx b/packages/frontend/src/pages/org-slug/layout.tsx new file mode 100644 index 00000000..c1be6b8c --- /dev/null +++ b/packages/frontend/src/pages/org-slug/layout.tsx @@ -0,0 +1,31 @@ +import { Sidebar } from 'components/shared/Sidebar'; +import { OctokitProvider } from 'context/OctokitContext'; +import React, { ComponentPropsWithoutRef } from 'react'; +import { Outlet } from 'react-router-dom'; +import { cn } from 'utils/classnames'; + +export interface DashboardLayoutProps + extends ComponentPropsWithoutRef<'section'> {} + +export const DashboardLayout = ({ + className, + children, + ...props +}: DashboardLayoutProps) => { + return ( +
+ +
+
+ + + +
+
+ {children} +
+ ); +}; diff --git a/packages/frontend/src/pages/org-slug/projects/Create.tsx b/packages/frontend/src/pages/org-slug/projects/Create.tsx deleted file mode 100644 index 2f12b981..00000000 --- a/packages/frontend/src/pages/org-slug/projects/Create.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { Outlet, Link, useParams } from 'react-router-dom'; - -import { IconButton } from '@material-tailwind/react'; - -import HorizontalLine from '../../../components/HorizontalLine'; - -const CreateProject = () => { - const { orgSlug } = useParams(); - return ( -
-
-
-

Create new project

-
-
- - - X - - -
-
- - -
- ); -}; - -export default CreateProject; diff --git a/packages/frontend/src/pages/org-slug/projects/create/index.tsx b/packages/frontend/src/pages/org-slug/projects/create/index.tsx index 6d2598f4..48c576a3 100644 --- a/packages/frontend/src/pages/org-slug/projects/create/index.tsx +++ b/packages/frontend/src/pages/org-slug/projects/create/index.tsx @@ -1,29 +1,36 @@ import React from 'react'; -import templates from '../../../../assets/templates'; -import TemplateCard from '../../../../components/projects/create/TemplateCard'; -import RepositoryList from '../../../../components/projects/create/RepositoryList'; -import ConnectAccount from '../../../../components/projects/create/ConnectAccount'; -import { useOctokit } from '../../../../context/OctokitContext'; +import templates from 'assets/templates'; +import { RepositoryList } from 'components/projects/create/RepositoryList'; +import ConnectAccount from 'components/projects/create/ConnectAccount'; +import { useOctokit } from 'context/OctokitContext'; +import { Heading } from 'components/shared/Heading'; +import { TemplateCard } from 'components/projects/create/TemplateCard'; const NewProject = () => { const { octokit, updateAuth, isAuth } = useOctokit(); return isAuth ? ( <> -
Start with template
-
- {templates.map((template) => { - return ( - - ); - })} +
+ + Start with template + +
+ {templates.map((template) => { + return ( + + ); + })} +
-
Import a repository
+ + Import a repository + ) : ( diff --git a/packages/frontend/src/pages/org-slug/projects/create/layout.tsx b/packages/frontend/src/pages/org-slug/projects/create/layout.tsx new file mode 100644 index 00000000..3dad337a --- /dev/null +++ b/packages/frontend/src/pages/org-slug/projects/create/layout.tsx @@ -0,0 +1,39 @@ +import React, { ComponentPropsWithoutRef } from 'react'; +import { Link, Outlet, useParams } from 'react-router-dom'; + +import { Heading } from 'components/shared/Heading'; +import { WavyBorder } from 'components/shared/WavyBorder'; +import { Button } from 'components/shared/Button'; +import { CrossIcon } from 'components/shared/CustomIcon'; +import { cn } from 'utils/classnames'; + +export interface CreateProjectLayoutProps + extends ComponentPropsWithoutRef<'section'> {} + +export const CreateProjectLayout = ({ + className, + ...props +}: CreateProjectLayoutProps) => { + const { orgSlug } = useParams(); + + return ( +
+
+
+ + Create new project + + + + +
+ +
+
+ +
+
+ ); +}; diff --git a/packages/frontend/src/pages/org-slug/projects/routes.tsx b/packages/frontend/src/pages/org-slug/projects/routes.tsx index 993e22b3..e4dd5756 100644 --- a/packages/frontend/src/pages/org-slug/projects/routes.tsx +++ b/packages/frontend/src/pages/org-slug/projects/routes.tsx @@ -1,16 +1,16 @@ import React from 'react'; -import CreateProject from './Create'; import Id from './Id'; import AddDomain from './id/settings/domains/add'; import { createProjectRoutes } from './create/routes'; import { projectTabRoutes } from './id/routes'; import { addDomainRoutes } from './id/settings/domains/add/routes'; +import { CreateProjectLayout } from './create/layout'; export const projectsRoutesWithoutSearch = [ { path: 'create', - element: , + element: , children: createProjectRoutes, }, { diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index eb0bb315..c362e898 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -158,6 +158,7 @@ export default withMT({ field: '0px 1px 2px rgba(0, 0, 0, 0.04)', inset: 'inset 0px 1px 0px rgba(8, 47, 86, 0.06)', card: '0px 0px 0px 1px #E8F0F7, 0px 2px 4px rgba(8, 47, 86, 0.04)', + 'card-sm': '0px 1px 2px -1px rgba(4, 25, 47, 0.08)', }, spacing: { 2.5: '0.625rem', From b1bf47d10451b3eb028f710c61190589aee2ac25 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Wed, 28 Feb 2024 16:50:55 +0700 Subject: [PATCH 13/13] [T-4921: feat] Update project card component (#136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🎨 style: add hover interaction to the card * ⚡️ feat: make the whole card clickable * 🎨 style: adjust hovered background for wavy border * ♻️ refactor: move wavy border class to project card theme * 🎨 style: add transition when hover * 📝 docs: add todo to experiment using `Link` componnt --- .../projects/ProjectCard/ProjectCard.theme.ts | 11 ++++++- .../projects/ProjectCard/ProjectCard.tsx | 32 +++++++++++++------ .../pages/org-slug/projects/create/index.tsx | 2 +- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts index 41cfe1c8..db662ebc 100644 --- a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts +++ b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts @@ -8,6 +8,7 @@ export const projectCardTheme = tv({ 'rounded-2xl', 'flex', 'flex-col', + 'group', ], upperContent: ['px-4', 'py-4', 'flex', 'items-start', 'gap-3', 'relative'], content: ['flex', 'flex-col', 'gap-1', 'flex-1'], @@ -20,13 +21,15 @@ export const projectCardTheme = tv({ description: ['text-xs', 'text-elements-low-em'], icons: ['flex', 'items-center', 'gap-1'], lowerContent: [ - 'bg-surface-card-hovered', + 'transition-colors', + 'duration-150', 'px-4', 'py-4', 'flex', 'flex-col', 'gap-2', 'rounded-b-2xl', + 'group-hover:bg-surface-card-hovered', ], latestDeployment: ['flex', 'items-center', 'gap-2'], deploymentStatusContainer: [ @@ -46,6 +49,12 @@ export const projectCardTheme = tv({ 'items-center', 'gap-2', ], + wavyBorder: [ + 'bg-surface-card', + 'transition-colors', + 'duration-150', + 'group-hover:bg-surface-card-hovered', + ], }, variants: { status: { diff --git a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx index 5c7efb15..1c91e51d 100644 --- a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx +++ b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx @@ -1,4 +1,8 @@ -import React, { ComponentPropsWithoutRef, MouseEvent } from 'react'; +import React, { + ComponentPropsWithoutRef, + MouseEvent, + useCallback, +} from 'react'; import { ProjectCardTheme, projectCardTheme } from './ProjectCard.theme'; import { Project } from 'gql-client'; import { Button } from 'components/shared/Button'; @@ -11,7 +15,7 @@ import { WarningDiamondIcon, } from 'components/shared/CustomIcon'; import { relativeTimeMs } from 'utils/time'; -import { Link } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { Avatar } from 'components/shared/Avatar'; import { getInitials } from 'utils/geInitials'; import { @@ -27,6 +31,8 @@ export interface ProjectCardProps project: Project; } +// TODO: Update the whole component to use `Link` from `react-router-dom` and remove the `useNavigate` hook, +// currently it's not possible to use `Link` because the dot menu is not a direct child of the `Link` component export const ProjectCard = ({ className, project, @@ -38,14 +44,24 @@ export const ProjectCard = ({ // TODO: Update this to use the actual status from the API const hasError = status === 'failure'; + const navigate = useNavigate(); + const handleOptionsClick = ( e: MouseEvent, ) => { e.stopPropagation(); }; + const handleClick = useCallback(() => { + navigate(`projects/${project.id}`); + }, [project.id, navigate]); + return ( -
+
{/* Upper content */}
{/* Icon container */} @@ -54,14 +70,13 @@ export const ProjectCard = ({ imageSrc={project.icon} initials={getInitials(project.name)} /> - {/*
*/} {/* Title and website */} - +

{project.name}

{project.deployments[0]?.domain?.name ?? 'No domain'}

- +
{/* Icons */}
{hasError && } @@ -87,10 +102,7 @@ export const ProjectCard = ({
{/* Wave */} - + {/* Lower content */}
{/* Latest deployment */} diff --git a/packages/frontend/src/pages/org-slug/projects/create/index.tsx b/packages/frontend/src/pages/org-slug/projects/create/index.tsx index 48c576a3..1c86ee3b 100644 --- a/packages/frontend/src/pages/org-slug/projects/create/index.tsx +++ b/packages/frontend/src/pages/org-slug/projects/create/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import templates from 'assets/templates'; -import { RepositoryList } from 'components/projects/create/RepositoryList'; +import RepositoryList from 'components/projects/create/RepositoryList'; import ConnectAccount from 'components/projects/create/ConnectAccount'; import { useOctokit } from 'context/OctokitContext'; import { Heading } from 'components/shared/Heading';