From b82519301ceb7b3743323f38dce2cd2045400aa3 Mon Sep 17 00:00:00 2001 From: Ady Beraud <102751374+ady-beraud@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:41:08 +0200 Subject: [PATCH] Website UI design (#4829) **Fixed different issues** : - Multiple CSS fixes: font-size, colors, margins, z-index ... - Fixed hover on contributor avatars - Added link to contributors in footer - Made the year in the footer dynamic (2023 --> 2024) - Added name of contributor in "Thank you" section of Contributor page - Added footer in small screens - Made Activity Log Responsive - Fixed bug in "saving issues to DB", title was null everywhere. I needed to implement an "upsert" behaviour to update the existing database on init **To be noted :** There is the following bug on production happening on mobile when you refresh a second time : Screenshot 2024-04-05 at 01 30 58 It seems to be related to the following issue on mdx : [https://github.com/hashicorp/next-mdx-remote/issues/350](https://github.com/hashicorp/next-mdx-remote/issues/350) I added the following code that fixed this bug for me in development (this needs to be tested in production) : ``` const serialized = await serialize(content, { mdxOptions: { development: process.env.NODE_ENV === 'development', } }) ``` --------- Co-authored-by: Ady Beraud --- .../_components/contributors/ActivityLog.tsx | 27 ++++++++++++----- .../_components/contributors/AvatarGrid.tsx | 2 ++ .../contributors/CardContainer.tsx | 1 - .../contributors/ContentContainer.tsx | 2 +- .../app/_components/contributors/Header.tsx | 15 +++++++--- .../_components/contributors/ProfileCard.tsx | 10 ++++++- .../_components/contributors/ProfileInfo.tsx | 9 +++--- .../contributors/PullRequestItem.tsx | 7 +++-- .../_components/contributors/PullRequests.tsx | 1 + .../app/_components/contributors/ThankYou.tsx | 8 ++--- .../oss-friends/ContentContainer.tsx | 2 +- .../src/app/_components/releases/Line.tsx | 6 ++-- .../src/app/_components/releases/Release.tsx | 23 +++++++++----- .../src/app/_components/ui/icons/SvgIcons.tsx | 6 ++-- .../app/_components/ui/layout/Breadcrumbs.tsx | 2 +- .../ui/layout/ContentContainer.tsx | 2 +- .../_components/ui/layout/FooterDesktop.tsx | 14 +++++++-- .../_components/ui/layout/header/styled.ts | 8 ++++- .../src/app/_server-utils/get-posts.tsx | 5 ++-- .../src/app/contributors/[slug]/page.tsx | 2 +- .../app/contributors/api/save-prs-to-db.tsx | 3 +- .../src/app/contributors/page.tsx | 4 +-- .../twenty-website/src/database/database.ts | 30 ++++++++++++++++++- .../src/database/postgres/schema-postgres.ts | 2 +- .../src/database/sqlite/schema-sqlite.ts | 2 +- 25 files changed, 140 insertions(+), 53 deletions(-) diff --git a/packages/twenty-website/src/app/_components/contributors/ActivityLog.tsx b/packages/twenty-website/src/app/_components/contributors/ActivityLog.tsx index ecea57139..18323a6b7 100644 --- a/packages/twenty-website/src/app/_components/contributors/ActivityLog.tsx +++ b/packages/twenty-website/src/app/_components/contributors/ActivityLog.tsx @@ -1,10 +1,20 @@ 'use client'; -import { ResponsiveTimeRange } from '@nivo/calendar'; +import styled from '@emotion/styled'; +import { TimeRange } from '@nivo/calendar'; import { CardContainer } from '@/app/_components/contributors/CardContainer'; import { Title } from '@/app/_components/contributors/Title'; +const CalendarContentContainer = styled.div` + @media (max-width: 890px) { + overflow-x: auto; + &::-webkit-scrollbar { + display: none; + } + } +`; + export const ActivityLog = ({ data, }: { @@ -16,17 +26,20 @@ export const ActivityLog = ({ return ( Activity -
- + -
+
); }; diff --git a/packages/twenty-website/src/app/_components/contributors/AvatarGrid.tsx b/packages/twenty-website/src/app/_components/contributors/AvatarGrid.tsx index 50512ad2e..436f7bd1d 100644 --- a/packages/twenty-website/src/app/_components/contributors/AvatarGrid.tsx +++ b/packages/twenty-website/src/app/_components/contributors/AvatarGrid.tsx @@ -52,6 +52,8 @@ const AvatarItem = styled.div` transition: opacity 0.3s ease, visibility 0.3s; + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; } &:hover .username { diff --git a/packages/twenty-website/src/app/_components/contributors/CardContainer.tsx b/packages/twenty-website/src/app/_components/contributors/CardContainer.tsx index 7a2f828be..87b00e940 100644 --- a/packages/twenty-website/src/app/_components/contributors/CardContainer.tsx +++ b/packages/twenty-website/src/app/_components/contributors/CardContainer.tsx @@ -11,7 +11,6 @@ export const CardContainer = styled.div` background-color: #fafafa; @media (max-width: 810px) { - gap: 16px; padding: 24px; } `; diff --git a/packages/twenty-website/src/app/_components/contributors/ContentContainer.tsx b/packages/twenty-website/src/app/_components/contributors/ContentContainer.tsx index a24728a7f..a53f0e681 100644 --- a/packages/twenty-website/src/app/_components/contributors/ContentContainer.tsx +++ b/packages/twenty-website/src/app/_components/contributors/ContentContainer.tsx @@ -9,11 +9,11 @@ const Container = styled.div` width: 100%; max-width: 898px; padding: 40px; - gap: 40px; @media (max-width: 809px) { width: 100%; padding: 40px 24px 40px 24px; + gap: 24px; } `; diff --git a/packages/twenty-website/src/app/_components/contributors/Header.tsx b/packages/twenty-website/src/app/_components/contributors/Header.tsx index d9a8509bb..9b2bf3b73 100644 --- a/packages/twenty-website/src/app/_components/contributors/Header.tsx +++ b/packages/twenty-website/src/app/_components/contributors/Header.tsx @@ -4,13 +4,19 @@ import styled from '@emotion/styled'; const Title = styled.h2` font-size: 56px; - font-weight: 600; + font-weight: bold; color: #b3b3b3; - margin-bottom: 0px; + margin-bottom: 32px; margin-top: 64px; + text-align: center; + display: flex; + justify-items: center; + align-items: center; + flex-direction: column; @media (max-width: 810px) { - font-size: 28px; + font-size: 32px; + margin-bottom: 22px; } `; @@ -18,7 +24,8 @@ export const Header = () => { return ( <> - Our amazing <br /> <span style={{ color: 'black' }}>Contributors</span> + Our amazing <br /> + <span style={{ color: '#141414' }}>Contributors</span> ); diff --git a/packages/twenty-website/src/app/_components/contributors/ProfileCard.tsx b/packages/twenty-website/src/app/_components/contributors/ProfileCard.tsx index d24842430..ef066a8e5 100644 --- a/packages/twenty-website/src/app/_components/contributors/ProfileCard.tsx +++ b/packages/twenty-website/src/app/_components/contributors/ProfileCard.tsx @@ -10,6 +10,10 @@ const ProfileContainer = styled.div` gap: 32px; width: 100%; align-items: center; + @media (max-width: 600px) { + flex-direction: column; + align-items: start; + } `; const Avatar = styled.div` @@ -33,6 +37,10 @@ const Details = styled.div` flex-direction: column; gap: 4px; + @media (max-width: 810px) { + gap: 8px; + } + .username { font-size: 40px; font-weight: 700; @@ -42,7 +50,7 @@ const Details = styled.div` gap: 12px; @media (max-width: 810px) { - font-size: 24px; + font-size: 32px; line-height: 28.8px; } } diff --git a/packages/twenty-website/src/app/_components/contributors/ProfileInfo.tsx b/packages/twenty-website/src/app/_components/contributors/ProfileInfo.tsx index 435a93cd2..2b6003100 100644 --- a/packages/twenty-website/src/app/_components/contributors/ProfileInfo.tsx +++ b/packages/twenty-website/src/app/_components/contributors/ProfileInfo.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { CardContainer } from '@/app/_components/contributors/CardContainer'; +import { Theme } from '@/app/_components/ui/theme/theme'; const Container = styled(CardContainer)` flex-direction: row; @@ -21,8 +22,8 @@ const Container = styled(CardContainer)` .title { font-size: 24px; - color: #b3b3b3; - margin: 0; + color: ${Theme.text.color.quarternary}; + margin: 8px; @media (max-width: 810px) { font-size: 20px; @@ -32,7 +33,7 @@ const Container = styled(CardContainer)` .value { font-size: 56px; font-weight: 700; - color: #474747; + color: ${Theme.text.color.secondary}; @media (max-width: 810px) { font-size: 32px; @@ -72,7 +73,7 @@ export const ProfileInfo = ({
-

Rank

+

Ranking

{rank}%
diff --git a/packages/twenty-website/src/app/_components/contributors/PullRequestItem.tsx b/packages/twenty-website/src/app/_components/contributors/PullRequestItem.tsx index edb57d0a1..617ed7c17 100644 --- a/packages/twenty-website/src/app/_components/contributors/PullRequestItem.tsx +++ b/packages/twenty-website/src/app/_components/contributors/PullRequestItem.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { format } from 'date-fns'; import { PullRequestIcon } from '@/app/_components/ui/icons/SvgIcons'; +import { Theme } from '@/app/_components/ui/theme/theme'; import { formatIntoRelativeDate } from '@/shared-utils/formatIntoRelativeDate'; const StyledTooltip = styled(Tooltip)``; @@ -15,7 +16,7 @@ const Item = styled.div` const StyledTitle = styled.a` font-size: 24px; font-weight: 400; - color: #474747; + color: ${Theme.text.color.secondary}; margin: 0; text-decoration: none; @@ -27,6 +28,7 @@ const StyledTitle = styled.a` const StyledPrLink = styled.a` cursor: pointer; text-decoration: none; + color: ${Theme.text.color.quarternary} !important; &:hover { text-decoration: underline; @@ -38,7 +40,8 @@ const StyledDescription = styled.div` font-size: 20px; line-height: 28px; font-weight: 500; - color: #b3b3b3; + color: ${Theme.text.color.quarternary}; + margin-top: 4px; @media (max-width: 810px) { font-size: 18px; diff --git a/packages/twenty-website/src/app/_components/contributors/PullRequests.tsx b/packages/twenty-website/src/app/_components/contributors/PullRequests.tsx index f7822c622..c8367fc0b 100644 --- a/packages/twenty-website/src/app/_components/contributors/PullRequests.tsx +++ b/packages/twenty-website/src/app/_components/contributors/PullRequests.tsx @@ -10,6 +10,7 @@ const List = styled.div` display: flex; gap: 24px; flex-direction: column; + overflow: hidden; `; interface PullRequestsProps { list: { diff --git a/packages/twenty-website/src/app/_components/contributors/ThankYou.tsx b/packages/twenty-website/src/app/_components/contributors/ThankYou.tsx index a0a80dba5..141ba036c 100644 --- a/packages/twenty-website/src/app/_components/contributors/ThankYou.tsx +++ b/packages/twenty-website/src/app/_components/contributors/ThankYou.tsx @@ -6,7 +6,6 @@ import { CardContainer } from '@/app/_components/contributors/CardContainer'; import { HeartIcon } from '@/app/_components/ui/icons/SvgIcons'; const StyledTitle = styled.div` - display: flex; font-size: 24px; font-weight: 500; gap: 8px; @@ -18,20 +17,21 @@ const StyledTitle = styled.div` const StyledHeartIcon = styled(HeartIcon)` @media (max-width: 810px) { + display: inline-block !important; width: 16px !important; height: 16px !important; } `; interface ThankYouProps { - authorId: string; + username: string; } -export const ThankYou = ({ authorId }: ThankYouProps) => { +export const ThankYou = ({ username }: ThankYouProps) => { return ( - Thank you @{authorId} + Thank you @{username} ); diff --git a/packages/twenty-website/src/app/_components/oss-friends/ContentContainer.tsx b/packages/twenty-website/src/app/_components/oss-friends/ContentContainer.tsx index 130bb9041..cf5238e7b 100644 --- a/packages/twenty-website/src/app/_components/oss-friends/ContentContainer.tsx +++ b/packages/twenty-website/src/app/_components/oss-friends/ContentContainer.tsx @@ -11,7 +11,7 @@ const Container = styled.div` gap: 26px; @media (max-width: 809px) { width: 100%; - padding: 0px 12px 0px 12px; + padding: 0px 12px 40px 12px; } `; diff --git a/packages/twenty-website/src/app/_components/releases/Line.tsx b/packages/twenty-website/src/app/_components/releases/Line.tsx index 5d1f564fb..a0d618c7e 100644 --- a/packages/twenty-website/src/app/_components/releases/Line.tsx +++ b/packages/twenty-website/src/app/_components/releases/Line.tsx @@ -9,17 +9,17 @@ const StyledLineContainer = styled.div` @media (max-width: 810px) { width: auto; - margin: 24px 0; display: block; + margin: 24px 0px 64px; } `; const StyledLine = styled.div` height: 1px; background-color: #d9d9d9; - margin-bottom: 48px; + margin-bottom: 80px; margin-left: 148px; - margin-top: 48px; + margin-top: 40px; width: 100%; @media (max-width: 810px) { diff --git a/packages/twenty-website/src/app/_components/releases/Release.tsx b/packages/twenty-website/src/app/_components/releases/Release.tsx index 58b580578..ac3d952a0 100644 --- a/packages/twenty-website/src/app/_components/releases/Release.tsx +++ b/packages/twenty-website/src/app/_components/releases/Release.tsx @@ -6,6 +6,7 @@ import { compileMDX } from 'next-mdx-remote/rsc'; import remarkBehead from 'remark-behead'; import gfm from 'remark-gfm'; +import { Theme } from '@/app/_components/ui/theme/theme'; import { ReleaseNote } from '@/app/releases/api/route'; const StyledContainer = styled.div` @@ -16,7 +17,6 @@ const StyledContainer = styled.div` @media (max-width: 810px) { width: auto; - margin: 24px 0; display: block; } `; @@ -35,17 +35,19 @@ const StyledVersion = styled.div` font-size: 20px; flex-flow: row; justify-content: space-between; + margin-bottom: 24px; } `; const StyledRelease = styled.span` - color: #141414; + color: ${Theme.text.color.quarternary}; + line-height: 140%; `; const StyledDate = styled.span` - color: #474747; - font-size: 16px; + color: ${Theme.text.color.secondary}; font-weight: 400; + font-size: ${Theme.font.size.sm}; `; const StlyedContent = styled.div` @@ -54,16 +56,20 @@ const StlyedContent = styled.div` gap: 64px; h3 { - color: #141414; + color: ${Theme.text.color.primary}; + font-weight: 700; font-size: 40px; margin: 0; } p { - color: #474747; + color: ${Theme.text.color.secondary}; + font-family: ${Theme.font.family}; font-size: 16px; line-height: 28.8px; font-weight: 400; + margin: 40px 0px; + text-align: justify; } img { @@ -73,16 +79,16 @@ const StlyedContent = styled.div` @media (max-width: 810px) { h3 { font-size: 24px; - margin: 24px 0 40px; } } `; const gabarito = Gabarito({ - weight: ['400', '500'], + weight: ['400', '500', '600', '700'], subsets: ['latin'], display: 'swap', adjustFontFallback: false, + variable: '--font-gabarito', }); export const Release = async ({ release }: { release: ReleaseNote }) => { @@ -92,6 +98,7 @@ export const Release = async ({ release }: { release: ReleaseNote }) => { source: release.content, options: { mdxOptions: { + development: process.env.NODE_ENV === 'development', remarkPlugins: [gfm, [remarkBehead, { depth: 2 }]], }, }, diff --git a/packages/twenty-website/src/app/_components/ui/icons/SvgIcons.tsx b/packages/twenty-website/src/app/_components/ui/icons/SvgIcons.tsx index 91f76461b..e8498ebf0 100644 --- a/packages/twenty-website/src/app/_components/ui/icons/SvgIcons.tsx +++ b/packages/twenty-website/src/app/_components/ui/icons/SvgIcons.tsx @@ -139,7 +139,9 @@ export const PullRequestIcon = ({ size = 'S', color = 'rgb(179,179,179)' }) => { export const HeartIcon = ({ size = 'S', color = 'rgb(179,179,179)' }) => { const dimension = getSize(size); return ( -
+ { strokeLinejoin="round" /> -
+ ); }; diff --git a/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx b/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx index 830049c7a..88a4a6310 100644 --- a/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx +++ b/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx @@ -30,7 +30,7 @@ const ExternalLinkItem = styled.a` `; const ActivePage = styled.span` - color: ${Theme.text.color.secondary}; + color: ${Theme.text.color.primary}; font-weight: ${Theme.font.weight.medium}; `; diff --git a/packages/twenty-website/src/app/_components/ui/layout/ContentContainer.tsx b/packages/twenty-website/src/app/_components/ui/layout/ContentContainer.tsx index 40d3b1228..556401a28 100644 --- a/packages/twenty-website/src/app/_components/ui/layout/ContentContainer.tsx +++ b/packages/twenty-website/src/app/_components/ui/layout/ContentContainer.tsx @@ -9,7 +9,7 @@ const Container = styled.div` padding: 0px 96px 0px 96px; @media (max-width: 809px) { width: 100%; - padding: 0px 12px 0px 12px; + padding: 0px 24px 0px 24px; } `; diff --git a/packages/twenty-website/src/app/_components/ui/layout/FooterDesktop.tsx b/packages/twenty-website/src/app/_components/ui/layout/FooterDesktop.tsx index 7015e72c1..73e092aa9 100644 --- a/packages/twenty-website/src/app/_components/ui/layout/FooterDesktop.tsx +++ b/packages/twenty-website/src/app/_components/ui/layout/FooterDesktop.tsx @@ -19,7 +19,7 @@ const FooterContainer = styled.div` color: rgb(129, 129, 129); gap: 32px; @media (max-width: 809px) { - display: none; + padding: 36px 24px; } `; @@ -28,6 +28,9 @@ const LeftSideFooter = styled.div` display: flex; flex-direction: column; gap: 16px; + @media (max-width: 809px) { + display: none; + } `; const RightSideFooter = styled.div` @@ -35,6 +38,10 @@ const RightSideFooter = styled.div` justify-content: space-between; gap: 48px; height: 146px; + @media (max-width: 809px) { + flex-direction: column; + height: fit-content; + } `; const RightSideFooterColumn = styled.div` @@ -96,6 +103,9 @@ export const FooterDesktop = () => { Other + + Contributors + OSS Friends @@ -120,7 +130,7 @@ export const FooterDesktop = () => { >
© - 2023 Twenty PBC + {new Date().getFullYear()} Twenty PBC
{ const entries = fs.readdirSync(filePath, { withFileTypes: true }); @@ -99,13 +99,14 @@ async function parseFrontMatterAndCategory( return parsedDirectory; } -export async function compileMDXFile(filePath: string, addToc: boolean = true) { +export async function compileMDXFile(filePath: string, addToc = true) { const fileContent = fs.readFileSync(filePath, 'utf8'); const compiled = await compileMDX<{ title: string; position?: number }>({ source: fileContent, options: { parseFrontmatter: true, mdxOptions: { + development: process.env.NODE_ENV === 'development', remarkPlugins: [gfm], rehypePlugins: [rehypeSlug, ...(addToc ? [toc] : [])], }, diff --git a/packages/twenty-website/src/app/contributors/[slug]/page.tsx b/packages/twenty-website/src/app/contributors/[slug]/page.tsx index 1bcde3cbe..0a916fc54 100644 --- a/packages/twenty-website/src/app/contributors/[slug]/page.tsx +++ b/packages/twenty-website/src/app/contributors/[slug]/page.tsx @@ -127,7 +127,7 @@ export default async function ({ params }: { params: { slug: string } }) { }[] } /> - + ); diff --git a/packages/twenty-website/src/app/contributors/api/save-prs-to-db.tsx b/packages/twenty-website/src/app/contributors/api/save-prs-to-db.tsx index 3cb93350c..2f5d37f6c 100644 --- a/packages/twenty-website/src/app/contributors/api/save-prs-to-db.tsx +++ b/packages/twenty-website/src/app/contributors/api/save-prs-to-db.tsx @@ -15,6 +15,7 @@ export async function savePRsToDB( if (pr.author == null) { continue; } + await insertMany( userModel, [ @@ -43,7 +44,7 @@ export async function savePRsToDB( authorId: pr.author.login, }, ], - { onConflictKey: 'id' }, + { onConflictKey: 'id', onConflictUpdateObject: { title: pr.title } }, ); for (const label of pr.labels.nodes) { diff --git a/packages/twenty-website/src/app/contributors/page.tsx b/packages/twenty-website/src/app/contributors/page.tsx index 4d00bdf59..8e553d330 100644 --- a/packages/twenty-website/src/app/contributors/page.tsx +++ b/packages/twenty-website/src/app/contributors/page.tsx @@ -47,9 +47,7 @@ const Contributors = async () => {
-
- -
+ ); diff --git a/packages/twenty-website/src/database/database.ts b/packages/twenty-website/src/database/database.ts index 49fdfe075..91cc0abd8 100644 --- a/packages/twenty-website/src/database/database.ts +++ b/packages/twenty-website/src/database/database.ts @@ -76,10 +76,25 @@ const findAll = (model: SQLiteTableWithColumns) => { const insertMany = async ( model: SQLiteTableWithColumns, data: any, - options?: { onConflictKey?: string }, + options?: { + onConflictKey?: string; + onConflictUpdateObject?: any; + }, ) => { if (isSqliteDriver) { const query = sqliteDb.insert(model).values(data); + + if (options?.onConflictUpdateObject) { + if (options?.onConflictKey) { + return query + .onConflictDoUpdate({ + target: [model[options.onConflictKey]], + set: options.onConflictUpdateObject, + }) + .execute(); + } + } + if (options?.onConflictKey) { return query .onConflictDoNothing({ @@ -87,10 +102,23 @@ const insertMany = async ( }) .execute(); } + return query.execute(); } if (isPgDriver) { const query = pgDb.insert(model).values(data); + + if (options?.onConflictUpdateObject) { + if (options?.onConflictKey) { + return query + .onConflictDoUpdate({ + target: [model[options.onConflictKey]], + set: options.onConflictUpdateObject, + }) + .execute(); + } + } + if (options?.onConflictKey) { return query .onConflictDoNothing({ diff --git a/packages/twenty-website/src/database/postgres/schema-postgres.ts b/packages/twenty-website/src/database/postgres/schema-postgres.ts index 44ef1b48a..bb5f429f6 100644 --- a/packages/twenty-website/src/database/postgres/schema-postgres.ts +++ b/packages/twenty-website/src/database/postgres/schema-postgres.ts @@ -9,7 +9,7 @@ export const pgUsers = pgTable('users', { export const pgPullRequests = pgTable('pullRequests', { id: text('id').primaryKey(), - name: text('title'), + title: text('title'), body: text('body'), url: text('url'), createdAt: text('createdAt'), diff --git a/packages/twenty-website/src/database/sqlite/schema-sqlite.ts b/packages/twenty-website/src/database/sqlite/schema-sqlite.ts index 21c424831..60ca22b35 100644 --- a/packages/twenty-website/src/database/sqlite/schema-sqlite.ts +++ b/packages/twenty-website/src/database/sqlite/schema-sqlite.ts @@ -9,7 +9,7 @@ export const sqlLiteUsers = sqliteTable('users', { export const sqlLitePullRequests = sqliteTable('pullRequests', { id: text('id').primaryKey(), - name: text('title'), + title: text('title'), body: text('body'), url: text('url'), createdAt: text('createdAt'),