From ab72bbb03ff3752b3be64ba127c99d59d574949f Mon Sep 17 00:00:00 2001 From: Nabarun Gogoi Date: Tue, 27 Feb 2024 14:16:36 +0530 Subject: [PATCH 1/2] Update template repo links (#124) --- .../deployer/records/application-deployment-request.yml | 8 ++++---- packages/deployer/records/application-record.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/deployer/records/application-deployment-request.yml b/packages/deployer/records/application-deployment-request.yml index 13061828..33cff83f 100644 --- a/packages/deployer/records/application-deployment-request.yml +++ b/packages/deployer/records/application-deployment-request.yml @@ -8,11 +8,11 @@ record: env: LACONIC_HOSTED_CONFIG_app_server_url: https://snowballtools-base-api-001.apps.snowballtools.com # If GitHub client ID is changed, same ID and corresponding secret has to be set in backend config - LACONIC_HOSTED_CONFIG_app_github_clientid: 1ed99146e0d07aa62d44 - LACONIC_HOSTED_CONFIG_app_github_templaterepo: deep-stack/test-progressive-web-app + LACONIC_HOSTED_CONFIG_app_github_clientid: b7c63b235ca1dd5639ab + LACONIC_HOSTED_CONFIG_app_github_templaterepo: snowball-tools-platform/test-progressive-web-app # New config env after changes for image upload PWA - LACONIC_HOSTED_CONFIG_app_github_pwa_templaterepo: deep-stack/test-progressive-web-app - LACONIC_HOSTED_CONFIG_app_github_image_upload_templaterepo: deep-stack/image-upload-pwa-example + LACONIC_HOSTED_CONFIG_app_github_pwa_templaterepo: snowball-tools-platform/test-progressive-web-app + LACONIC_HOSTED_CONFIG_app_github_image_upload_templaterepo: snowball-tools-platform/image-upload-pwa-example LACONIC_HOSTED_CONFIG_app_wallet_connect_id: eda9ba18042a5ea500f358194611ece2 meta: # Set CURRENT_DATE_TIME; Use command date -u diff --git a/packages/deployer/records/application-record.yml b/packages/deployer/records/application-record.yml index 302bff8e..cc618548 100644 --- a/packages/deployer/records/application-record.yml +++ b/packages/deployer/records/application-record.yml @@ -1,6 +1,6 @@ record: type: ApplicationRecord - version: 0.0.5 + version: 0.0.6 repository_ref: 353fd0f6219a955be186b5914e93baa9058b4473 repository: ["https://git.vdb.to/cerc-io/snowballtools-base"] app_type: webapp From 8280f4c7f7639ff0fd2571c5b2710656391d5d6c Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Tue, 27 Feb 2024 21:16:38 +0700 Subject: [PATCH 2/2] [T-4902: feat] Update project card (#126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⚡️ feat: create wavy border component * ⚡️ feat: create project card component * ⚡️ feat: add new size in avatar * 🎨 style: add default border radius when the shape is default on the button * ⚡️ feat: create some icons for project card component * 🔧 chore: install and setup jetbrains mono font family * ⚡️ feat: create `getInitials` util function * 🎨 style: add jetbrains mono font to the tailwind config * ⚡️ feat: add warning error icon * ♻️ refactor: change `jetbrains-mono` to `mono` --- packages/frontend/package.json | 3 +- packages/frontend/public/wave-border.svg | 10 ++ .../src/components/projects/ProjectCard.tsx | 71 ---------- .../projects/ProjectCard/ProjectCard.theme.ts | 71 ++++++++++ .../projects/ProjectCard/ProjectCard.tsx | 124 ++++++++++++++++++ .../components/projects/ProjectCard/index.ts | 1 + .../components/shared/Avatar/Avatar.theme.ts | 3 + .../components/shared/Button/Button.theme.ts | 2 +- .../shared/CustomIcon/BranchIcon.tsx | 19 +++ .../shared/CustomIcon/ClockIcon.tsx | 19 +++ .../shared/CustomIcon/GitHubLogo.tsx | 19 +++ .../shared/CustomIcon/HorizontalDotIcon.tsx | 19 +++ .../shared/CustomIcon/WarningDiamondIcon.tsx | 19 +++ .../src/components/shared/CustomIcon/index.ts | 5 + .../shared/WavyBorder/WavyBorder.tsx | 16 +++ .../src/components/shared/WavyBorder/index.ts | 1 + packages/frontend/src/index.css | 8 ++ packages/frontend/src/index.tsx | 1 + .../frontend/src/pages/org-slug/index.tsx | 2 +- packages/frontend/src/utils/geInitials.ts | 13 ++ packages/frontend/tailwind.config.js | 2 + yarn.lock | 7 +- 22 files changed, 360 insertions(+), 75 deletions(-) create mode 100644 packages/frontend/public/wave-border.svg delete mode 100644 packages/frontend/src/components/projects/ProjectCard.tsx create mode 100644 packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts create mode 100644 packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx create mode 100644 packages/frontend/src/components/projects/ProjectCard/index.ts create mode 100644 packages/frontend/src/components/shared/CustomIcon/BranchIcon.tsx create mode 100644 packages/frontend/src/components/shared/CustomIcon/ClockIcon.tsx create mode 100644 packages/frontend/src/components/shared/CustomIcon/GitHubLogo.tsx create mode 100644 packages/frontend/src/components/shared/CustomIcon/HorizontalDotIcon.tsx create mode 100644 packages/frontend/src/components/shared/CustomIcon/WarningDiamondIcon.tsx create mode 100644 packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx create mode 100644 packages/frontend/src/components/shared/WavyBorder/index.ts create mode 100644 packages/frontend/src/utils/geInitials.ts diff --git a/packages/frontend/package.json b/packages/frontend/package.json index caf87b8b..e254640a 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "@fontsource-variable/jetbrains-mono": "^5.0.19", "@fontsource/inter": "^5.0.16", "@material-tailwind/react": "^2.1.7", - "@tanstack/react-query": "^5.22.2", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-popover": "^1.0.7", @@ -14,6 +14,7 @@ "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-query": "^5.22.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/packages/frontend/public/wave-border.svg b/packages/frontend/public/wave-border.svg new file mode 100644 index 00000000..94137bb5 --- /dev/null +++ b/packages/frontend/public/wave-border.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/frontend/src/components/projects/ProjectCard.tsx b/packages/frontend/src/components/projects/ProjectCard.tsx deleted file mode 100644 index 157a0ed4..00000000 --- a/packages/frontend/src/components/projects/ProjectCard.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import { Project } from 'gql-client'; - -import { - Menu, - MenuHandler, - MenuList, - MenuItem, - Typography, - Avatar, -} from '@material-tailwind/react'; - -import { relativeTimeMs } from '../../utils/time'; - -interface ProjectCardProps { - project: Project; -} - -const ProjectCard: React.FC = ({ project }) => { - return ( -
-
- -
- - {project.name} - - {project.deployments[0]?.domain?.name ?? - 'No Production Deployment'} - - -
- - - - - - ^ Project settings - - ^ Delete project - - - -
-
- {project.deployments.length > 0 ? ( - <> - - ^ {project.deployments[0].commitMessage} - - - {relativeTimeMs(project.deployments[0].createdAt)} on ^  - {project.deployments[0].branch} - - - ) : ( - - No Production deployment - - )} -
-
- ); -}; - -export default ProjectCard; diff --git a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts new file mode 100644 index 00000000..41cfe1c8 --- /dev/null +++ b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.theme.ts @@ -0,0 +1,71 @@ +import { VariantProps, tv } from 'tailwind-variants'; + +export const projectCardTheme = tv({ + slots: { + wrapper: [ + 'bg-surface-card', + 'shadow-card', + 'rounded-2xl', + 'flex', + 'flex-col', + ], + upperContent: ['px-4', 'py-4', 'flex', 'items-start', 'gap-3', 'relative'], + content: ['flex', 'flex-col', 'gap-1', 'flex-1'], + title: [ + 'text-sm', + 'font-medium', + 'text-elements-high-em', + 'tracking-[-0.006em]', + ], + description: ['text-xs', 'text-elements-low-em'], + icons: ['flex', 'items-center', 'gap-1'], + lowerContent: [ + 'bg-surface-card-hovered', + 'px-4', + 'py-4', + 'flex', + 'flex-col', + 'gap-2', + 'rounded-b-2xl', + ], + latestDeployment: ['flex', 'items-center', 'gap-2'], + deploymentStatusContainer: [ + 'h-3', + 'w-3', + 'flex', + 'items-center', + 'justify-center', + ], + deploymentStatus: ['w-1', 'h-1', 'rounded-full'], + deploymentName: ['text-xs', 'text-elements-low-em'], + deploymentText: [ + 'text-xs', + 'text-elements-low-em', + 'font-mono', + 'flex', + 'items-center', + 'gap-2', + ], + }, + variants: { + status: { + success: { + deploymentStatus: ['bg-emerald-500'], + }, + 'in-progress': { + deploymentStatus: ['bg-orange-400'], + }, + failure: { + deploymentStatus: ['bg-rose-500'], + }, + pending: { + deploymentStatus: ['bg-gray-500'], + }, + }, + }, + defaultVariants: { + status: 'pending', + }, +}); + +export type ProjectCardTheme = VariantProps; diff --git a/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx new file mode 100644 index 00000000..85603037 --- /dev/null +++ b/packages/frontend/src/components/projects/ProjectCard/ProjectCard.tsx @@ -0,0 +1,124 @@ +import React, { ComponentPropsWithoutRef, MouseEvent } from 'react'; +import { ProjectCardTheme, projectCardTheme } from './ProjectCard.theme'; +import { Project } from 'gql-client'; +import { Button } from 'components/shared/Button'; +import { WavyBorder } from 'components/shared/WavyBorder'; +import { + BranchIcon, + ClockIcon, + GitHubLogo, + HorizontalDotIcon, + WarningDiamondIcon, +} from 'components/shared/CustomIcon'; +import { relativeTimeMs } from 'utils/time'; +import { Link } from 'react-router-dom'; +import { Avatar } from 'components/shared/Avatar'; +import { getInitials } from 'utils/geInitials'; +import { + Menu, + MenuHandler, + MenuItem, + MenuList, +} from '@material-tailwind/react'; + +export interface ProjectCardProps + extends ComponentPropsWithoutRef<'div'>, + ProjectCardTheme { + project: Project; +} + +export const ProjectCard = ({ + className, + project, + status = 'failure', + ...props +}: ProjectCardProps) => { + const theme = projectCardTheme(); + const hasDeployment = project.deployments.length > 0; + // TODO: Update this to use the actual status from the API + const hasError = status === 'failure'; + + const handleOptionsClick = ( + e: MouseEvent, + ) => { + e.stopPropagation(); + }; + + return ( +
+ {/* Upper content */} +
+ {/* Icon container */} + + {/*
*/} + {/* Title and website */} + +

{project.name}

+

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

+ + {/* Icons */} +
+ {hasError && } + + + + + + Project settings + + Delete project + + + +
+
+ {/* Wave */} + + {/* Lower content */} +
+ {/* Latest deployment */} +
+ {/* Dot icon */} +
+
+
+

+ {hasDeployment + ? project.deployments[0]?.commitMessage + : 'No production deployment'} +

+
+ {/* Deployment and branch name */} +
+ {hasDeployment ? ( + <> + + {relativeTimeMs(project.deployments[0].createdAt)} on + + {project.deployments[0].branch} + + ) : ( + <> + + Created {relativeTimeMs(project.createdAt)} + + )} +
+
+
+ ); +}; diff --git a/packages/frontend/src/components/projects/ProjectCard/index.ts b/packages/frontend/src/components/projects/ProjectCard/index.ts new file mode 100644 index 00000000..c9169b8b --- /dev/null +++ b/packages/frontend/src/components/projects/ProjectCard/index.ts @@ -0,0 +1 @@ +export * from './ProjectCard'; diff --git a/packages/frontend/src/components/shared/Avatar/Avatar.theme.ts b/packages/frontend/src/components/shared/Avatar/Avatar.theme.ts index bc594274..b7522cfe 100644 --- a/packages/frontend/src/components/shared/Avatar/Avatar.theme.ts +++ b/packages/frontend/src/components/shared/Avatar/Avatar.theme.ts @@ -58,6 +58,9 @@ export const avatarTheme = tv( 44: { base: ['rounded-xl', 'h-[44px]', 'w-[44px]', 'text-sm'], }, + 48: { + base: ['rounded-xl', 'h-[48px]', 'w-[48px]', 'text-sm'], + }, }, }, defaultVariants: { diff --git a/packages/frontend/src/components/shared/Button/Button.theme.ts b/packages/frontend/src/components/shared/Button/Button.theme.ts index 194c6550..a2cc19ca 100644 --- a/packages/frontend/src/components/shared/Button/Button.theme.ts +++ b/packages/frontend/src/components/shared/Button/Button.theme.ts @@ -26,7 +26,7 @@ export const buttonTheme = tv( true: 'w-full', }, shape: { - default: '', + default: 'rounded-lg', rounded: 'rounded-full', }, iconOnly: { diff --git a/packages/frontend/src/components/shared/CustomIcon/BranchIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/BranchIcon.tsx new file mode 100644 index 00000000..aa1f71b0 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/BranchIcon.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const BranchIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/ClockIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/ClockIcon.tsx new file mode 100644 index 00000000..ceba322b --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/ClockIcon.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const ClockIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/GitHubLogo.tsx b/packages/frontend/src/components/shared/CustomIcon/GitHubLogo.tsx new file mode 100644 index 00000000..4a650760 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/GitHubLogo.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const GitHubLogo = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/HorizontalDotIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/HorizontalDotIcon.tsx new file mode 100644 index 00000000..bb77271f --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/HorizontalDotIcon.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const HorizontalDotIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/WarningDiamondIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/WarningDiamondIcon.tsx new file mode 100644 index 00000000..cb60f239 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/WarningDiamondIcon.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const WarningDiamondIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 2b9834ff..471d8272 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -25,3 +25,8 @@ export * from './NotificationBellIcon'; export * from './PencilIcon'; export * from './CheckRadioIcon'; export * from './ChevronDownIcon'; +export * from './BranchIcon'; +export * from './GitHubLogo'; +export * from './ClockIcon'; +export * from './HorizontalDotIcon'; +export * from './WarningDiamondIcon'; diff --git a/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx b/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx new file mode 100644 index 00000000..45bc7234 --- /dev/null +++ b/packages/frontend/src/components/shared/WavyBorder/WavyBorder.tsx @@ -0,0 +1,16 @@ +import React, { ComponentPropsWithoutRef } from 'react'; +import { cn } from 'utils/classnames'; + +export interface WavyBorderProps extends ComponentPropsWithoutRef<'div'> {} + +export const WavyBorder = ({ + className, + children, + ...props +}: WavyBorderProps) => { + return ( +
+ {children} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/WavyBorder/index.ts b/packages/frontend/src/components/shared/WavyBorder/index.ts new file mode 100644 index 00000000..1b635a77 --- /dev/null +++ b/packages/frontend/src/components/shared/WavyBorder/index.ts @@ -0,0 +1 @@ +export * from './WavyBorder'; diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index c1375286..9a276aba 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -6,4 +6,12 @@ .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/index.tsx b/packages/frontend/src/index.tsx index b80655cb..55beb6d2 100644 --- a/packages/frontend/src/index.tsx +++ b/packages/frontend/src/index.tsx @@ -7,6 +7,7 @@ import { ThemeProvider } from '@material-tailwind/react'; import './index.css'; import '@fontsource/inter'; +import '@fontsource-variable/jetbrains-mono'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { GQLClientProvider } from './context/GQLClientContext'; diff --git a/packages/frontend/src/pages/org-slug/index.tsx b/packages/frontend/src/pages/org-slug/index.tsx index 8fed8636..406c7639 100644 --- a/packages/frontend/src/pages/org-slug/index.tsx +++ b/packages/frontend/src/pages/org-slug/index.tsx @@ -5,9 +5,9 @@ import { Button } from 'components/shared/Button'; import { Typography, Chip } from '@material-tailwind/react'; -import ProjectCard from '../../components/projects/ProjectCard'; import { useGQLClient } from '../../context/GQLClientContext'; import { PlusIcon } from 'components/shared/CustomIcon'; +import { ProjectCard } from 'components/projects/ProjectCard'; const Projects = () => { const client = useGQLClient(); diff --git a/packages/frontend/src/utils/geInitials.ts b/packages/frontend/src/utils/geInitials.ts new file mode 100644 index 00000000..c78f8362 --- /dev/null +++ b/packages/frontend/src/utils/geInitials.ts @@ -0,0 +1,13 @@ +/** + * Get initials from a full name. + * + * @param {string} name - The full name string from which to get the initials. + * @returns {string} A string of initials. + */ +export function getInitials(name: string): string { + return name + .split(' ') + .filter((n) => n) + .map((n) => n[0].toUpperCase()) + .join(''); +} diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index 2ddac405..5bb49bf1 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -14,6 +14,7 @@ export default withMT({ }, fontFamily: { sans: ['Inter', 'sans-serif'], + mono: ['JetBrains Mono', 'monospace'], }, fontSize: { '2xs': '0.625rem', @@ -155,6 +156,7 @@ export default withMT({ '0px 3px 20px rgba(8, 47, 86, 0.1), 0px 0px 4px rgba(8, 47, 86, 0.14)', 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)', }, spacing: { 2.5: '0.625rem', diff --git a/yarn.lock b/yarn.lock index 3ec5b346..60ab1754 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2160,6 +2160,11 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== +"@fontsource-variable/jetbrains-mono@^5.0.19": + version "5.0.19" + resolved "https://registry.yarnpkg.com/@fontsource-variable/jetbrains-mono/-/jetbrains-mono-5.0.19.tgz#e718de646e83b7caaeee484d2e18e1e3680ba8e1" + integrity sha512-7PTG1Kp3B/FgoNVPT8da4humj5JxQYxTtO08ZPS2IfanS37Yb/WShbgScnG/iupuFwiRnHVkIuC/2czxItxmyg== + "@fontsource/inter@^5.0.16": version "5.0.16" resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-5.0.16.tgz#b858508cdb56dcbbf3166903122851e2fbd16b50" @@ -8756,7 +8761,7 @@ dotenv@~16.3.1: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.2.tgz#3cb611ce5a63002dbabf7c281bc331f69d28f03f" integrity sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ== -downshift@^8.2.3: +downshift@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/downshift/-/downshift-8.3.2.tgz#35cccfdadfe183a9e6bceb1dca68a6a592bb5602" integrity sha512-kO5mnwMbWB1OIPgIO4wxK0HtSJbaPzx3XTOcnN36I6i08iVc4C2Fftye3UZYVN+W03b13o1kEmN2118G5vcgeQ==