-
Notifications
You must be signed in to change notification settings - Fork 356
Created home page navbar & setup project module and its route #1343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3039e9e
0295d90
85e3dc2
9a48dc3
f88767d
f0922ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,17 @@ | ||
| export enum ROUTES_PAGE_V1 { | ||
| HOME = 'home', | ||
| SETTINGS = 'settings', | ||
| } | ||
|
|
||
| export enum ROUTES_V1 { | ||
| HOME = '/v1/home', | ||
| SETTINGS = '/v1/settings', | ||
| SETTINGS_PROFILE = '/profile', | ||
| } | ||
|
|
||
| export enum ROUTES_PAGE_V1 { | ||
| HOME = 'home', | ||
| SETTINGS = 'settings', | ||
| export enum ROUTES_HOME_V1 { | ||
| PROJECT = '/:project_id', | ||
| } | ||
|
|
||
| export enum ROUTES_SETTINGS_V1 { | ||
| PROFILE = '/profile', | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| import { lazy } from 'react'; | ||
|
|
||
| export const ProjectLazyComponentV1 = lazy(() => import('./project/v1')); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,232 @@ | ||
| import { useState } from 'react'; | ||
| import { Box, Button, useTheme } from '@mui/material'; | ||
| import { OutputBlockData } from '@editorjs/editorjs'; | ||
| import A2ZTypography from '../../../../../../shared/components/atoms/typography'; | ||
|
|
||
| const ParagraphBlock = ({ text }: { text: string }) => { | ||
| return ( | ||
| <A2ZTypography | ||
| variant="body1" | ||
| text="" | ||
| props={{ | ||
| dangerouslySetInnerHTML: { __html: text }, | ||
| sx: { lineHeight: 1.8 }, | ||
| }} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| const HeaderBlock = ({ level, text }: { level: number; text: string }) => { | ||
| const variant = level === 3 ? 'h5' : 'h4'; | ||
| const component = level === 3 ? 'h3' : 'h2'; | ||
| return ( | ||
| <A2ZTypography | ||
| variant={variant} | ||
| component={component} | ||
| text="" | ||
| props={{ | ||
| dangerouslySetInnerHTML: { __html: text }, | ||
| sx: { fontWeight: 600, mb: 2, mt: 3 }, | ||
| }} | ||
| /> | ||
| ); | ||
|
Comment on lines
+19
to
+32
|
||
| }; | ||
|
|
||
| const ImageBlock = ({ url, caption }: { url: string; caption: string }) => { | ||
| return ( | ||
| <Box | ||
| sx={{ | ||
| textAlign: 'center', | ||
| my: { xs: 2, md: 3 }, | ||
| '& img': { | ||
| maxWidth: '100%', | ||
| borderRadius: 2, | ||
| height: 'auto', | ||
| }, | ||
| }} | ||
| > | ||
| <img src={url} alt={caption} /> | ||
| {caption && ( | ||
| <A2ZTypography | ||
| variant="body2" | ||
| text={caption} | ||
| props={{ | ||
| sx: { | ||
| color: 'text.secondary', | ||
| mt: 1, | ||
| }, | ||
| }} | ||
| /> | ||
| )} | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| const QuoteBlock = ({ text, caption }: { text: string; caption: string }) => { | ||
| const theme = useTheme(); | ||
| return ( | ||
| <Box | ||
| sx={{ | ||
| bgcolor: 'action.hover', | ||
| borderLeft: `4px solid ${theme.palette.primary.main}`, | ||
| p: 2, | ||
| pl: 3, | ||
| my: { xs: 2, md: 3 }, | ||
| borderRadius: 1, | ||
| }} | ||
| > | ||
| <A2ZTypography | ||
| variant="h6" | ||
| text={text} | ||
| props={{ | ||
| sx: { | ||
| mb: caption ? 1 : 0, | ||
| fontStyle: 'italic', | ||
| }, | ||
| }} | ||
| /> | ||
| {caption && ( | ||
| <A2ZTypography | ||
| variant="body2" | ||
| text={caption} | ||
| props={{ | ||
| sx: { | ||
| color: 'primary.main', | ||
| }, | ||
| }} | ||
| /> | ||
| )} | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| const ListBlock = ({ style, items }: { style: string; items: string[] }) => { | ||
| const Tag = style === 'ordered' ? 'ol' : 'ul'; | ||
| const styleType = style === 'ordered' ? 'decimal' : 'disc'; | ||
| return ( | ||
| <Box | ||
| component={Tag} | ||
| sx={{ | ||
| pl: 3, | ||
| listStyleType: styleType, | ||
| my: { xs: 2, md: 3 }, | ||
| '& li': { | ||
| mb: 1, | ||
| }, | ||
| }} | ||
| > | ||
| {items.map((item, i) => ( | ||
| <li key={i}> | ||
| <A2ZTypography | ||
| variant="body1" | ||
| text="" | ||
| props={{ | ||
| dangerouslySetInnerHTML: { __html: item }, | ||
| }} | ||
| /> | ||
| </li> | ||
|
Comment on lines
+118
to
+127
|
||
| ))} | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| const CodeBlock = ({ code, language }: { code: string; language: string }) => { | ||
| const theme = useTheme(); | ||
| const codeText = code || ''; | ||
| const [copied, setCopied] = useState(false); | ||
|
|
||
| const handleCopy = async () => { | ||
| try { | ||
| await navigator.clipboard.writeText(codeText); | ||
| setCopied(true); | ||
| setTimeout(() => setCopied(false), 2000); | ||
| } catch { | ||
| setCopied(false); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <Box | ||
| sx={{ | ||
| bgcolor: theme.palette.mode === 'dark' ? 'grey.900' : 'grey.100', | ||
| color: 'text.primary', | ||
| p: 2, | ||
| borderRadius: 2, | ||
| overflow: 'auto', | ||
| position: 'relative', | ||
| my: { xs: 2, md: 3 }, | ||
| }} | ||
| > | ||
| {language && ( | ||
| <A2ZTypography | ||
| variant="caption" | ||
| text={language} | ||
| props={{ | ||
| sx: { | ||
| position: 'absolute', | ||
| top: 8, | ||
| left: 8, | ||
| opacity: 0.7, | ||
| textTransform: 'uppercase', | ||
| }, | ||
| }} | ||
| /> | ||
| )} | ||
| <Button | ||
| size="small" | ||
| onClick={handleCopy} | ||
| variant="outlined" | ||
| sx={{ | ||
| position: 'absolute', | ||
| top: 8, | ||
| right: 8, | ||
| minWidth: 'auto', | ||
| px: 1.5, | ||
| }} | ||
| > | ||
| {copied ? 'Copied' : 'Copy'} | ||
| </Button> | ||
| <Box | ||
| component="pre" | ||
| sx={{ | ||
| fontFamily: 'monospace', | ||
| mt: language ? 4 : 0, | ||
| whiteSpace: 'pre-wrap', | ||
| fontSize: '0.875rem', | ||
| lineHeight: 1.6, | ||
| }} | ||
| > | ||
| {codeText} | ||
| </Box> | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| const ProjectContent = ({ block }: { block: OutputBlockData }) => { | ||
| const { type, data } = block || {}; | ||
|
|
||
| switch (type) { | ||
| case 'paragraph': | ||
| return <ParagraphBlock text={data?.text ?? ''} />; | ||
| case 'header': | ||
| return <HeaderBlock level={data?.level ?? 2} text={data?.text ?? ''} />; | ||
| case 'image': | ||
| return ( | ||
| <ImageBlock url={data?.file?.url ?? ''} caption={data?.caption ?? ''} /> | ||
| ); | ||
| case 'quote': | ||
| return ( | ||
| <QuoteBlock text={data?.text ?? ''} caption={data?.caption ?? ''} /> | ||
| ); | ||
| case 'list': | ||
| return <ListBlock style={data?.style} items={data?.items || []} />; | ||
| case 'code': | ||
| return ( | ||
| <CodeBlock code={data?.code ?? ''} language={data?.language ?? ''} /> | ||
| ); | ||
| default: | ||
| return null; | ||
| } | ||
| }; | ||
|
|
||
| export default ProjectContent; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The empty
text=""prop passed toA2ZTypographywhen usingdangerouslySetInnerHTMLis unnecessary and could be confusing. When usingdangerouslySetInnerHTML, you should omit thetextprop entirely since it won't be used. This makes the component's API clearer.