Skip to content

Commit

Permalink
Create project page
Browse files Browse the repository at this point in the history
  • Loading branch information
henrycatalinismith committed May 27, 2024
1 parent aaf8b4e commit 01cc6e8
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 22 deletions.
51 changes: 51 additions & 0 deletions webapp/src/app/projects/[projectName]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Cache } from '@/Cache';
import MessageAdapterFactory from '@/utils/adapters/MessageAdapterFactory';
import { NextPage } from 'next';
import { notFound } from 'next/navigation';
import ProjectDashboard from '@/components/ProjectDashboard';
import { RepoGit } from '@/RepoGit';
import { ServerConfig } from '@/utils/serverConfig';

const ProjectPage: NextPage<{
params: { projectName: string };
}> = async ({ params }) => {
const serverConfig = await ServerConfig.read();
const project = serverConfig.projects.find(
(project) => project.name === params.projectName,
);

if (!project) {
return notFound();
}

await RepoGit.cloneIfNotExist(project);
const repoGit = await RepoGit.getRepoGit(project);
const lyraConfig = await repoGit.getLyraConfig();
const projectConfig = lyraConfig.getProjectConfigByPath(project.projectPath);
const msgAdapter = MessageAdapterFactory.createAdapter(projectConfig);
const messages = await msgAdapter.getMessages();
const store = await Cache.getProjectStore(projectConfig);
const languages = await Promise.all(
projectConfig.languages.map(async (lang) => {
const translations = await store.getTranslations(lang);
return {
href: `/projects/${project.name}/${lang}`,
language: lang,
messagesLeft: messages.length - Object.keys(translations).length,
progress: translations
? (Object.keys(translations).length / messages.length) * 100
: 0,
};
}),
);

return (
<ProjectDashboard
languages={languages}
messageCount={messages.length}
project={project.name}
/>
);
};

export default ProjectPage;
44 changes: 44 additions & 0 deletions webapp/src/components/CardGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Box, List } from '@mui/joy';
import { FC, ReactNode } from 'react';

export type CardGridProps = {
children: ReactNode;
heading?: ReactNode;
};

export const CardGrid: FC<CardGridProps> = ({ children, heading }) => {
return (
<Box
sx={{
'@media (min-width: 600px)': {
maxWidth: '900px',
},
display: 'flex',
flexDirection: 'column',
maxWidth: '600px',
rowGap: 2,
width: '100%',
}}
>
{heading && <Box>{heading}</Box>}
<List
sx={{
'@media (min-width: 650px)': {
columnGap: 2,
display: 'grid',
gridTemplateColumns: 'repeat(2, 300px);',
},
'@media (min-width: 950px)': {
gridTemplateColumns: 'repeat(3, 300px);',
},
display: 'flex',
flexDirection: 'column',
rowGap: 2,
width: '100%',
}}
>
{children}
</List>
</Box>
);
};
34 changes: 12 additions & 22 deletions webapp/src/components/HomeDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CardGrid } from '@/components/CardGrid';
import { FC } from 'react';
import { Box, List, Typography } from '@mui/joy';
import ProjectCard, { ProjectCardProps } from './ProjectCard';
import { Box, Typography } from '@mui/joy';
import ProjectCard, { ProjectCardProps } from '@/components/ProjectCard';

type HomeDashboardProps = {
projects: ProjectCardProps[];
Expand All @@ -15,30 +16,19 @@ const HomeDashboard: FC<HomeDashboardProps> = ({ projects }) => {
justifyContent="center"
minHeight="97vh"
>
<Typography alignSelf="flex-start" color="primary" component="h1">
Your Lyra Projects
</Typography>
<List
sx={{
'@media (min-width: 600px)': {
alignContent: 'center',
columnGap: 2,
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 300px));',
justifyContent: 'center',
},
alignItems: 'center',
display: 'flex',
flex: 1,
flexDirection: 'column',
rowGap: 2,
width: '100%',
}}
<CardGrid
heading={
<>
<Typography alignSelf="flex-start" component="h1">
Your Lyra Projects
</Typography>
</>
}
>
{projects.map((project, i) => (
<ProjectCard key={i} {...project} />
))}
</List>
</CardGrid>
</Box>
);
};
Expand Down
99 changes: 99 additions & 0 deletions webapp/src/components/LanguageCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { FC } from 'react';
import { Box, LinearProgress, Link, Typography } from '@mui/joy';

export type LanguageCardProps = {
/**
* The URL of the page containing the project's messages in this language.
*/

href: string;

/**
* The name of the language.
*/
language: string;

/**
* The number of messages left to translate in this language.
*/
messagesLeft: number;

/**
* The percentage of messages translated in this language. 0 means none, 100
* means all of them.
*/
progress: number;
};

/**
* A language card can be clicked to navigate to the page containing all a
* project's messages in that language. It display's the name of the language
* and some brief statistics about how complete the translation is.
*/
const LanguageCard: FC<LanguageCardProps> = ({
href,
language,
messagesLeft,
progress,
}) => {
return (
<Box component="li" sx={{ listStyleType: 'none' }} width="100%">
<Box
bgcolor="neutral.50"
border={1}
borderColor="transparent"
borderRadius={8}
display="flex"
flexDirection="column"
position="relative"
px={1}
py={2}
rowGap={1}
sx={{
':focus-within, :hover': {
outlineColor: 'focusVisible',
outlineStyle: 'solid',
outlineWidth: 1,
},
}}
>
<Typography component="h2">
<Link
href={href}
sx={{
'::after': {
bottom: 0,
content: '""',
left: 0,
position: 'absolute',
right: 0,
top: 0,
width: '100%',
},
':hover, :focus': {
outline: 'none',
textDecoration: 'none',
},
color: 'inherit',
position: 'inherit',
}}
>
{language}
</Link>
<LinearProgress
determinate
size="lg"
sx={{ backgroundColor: '#ffffff' }}
thickness={8}
value={Math.min(progress, 100)}
variant="outlined"
/>{' '}
</Typography>

<Typography>{messagesLeft} messages to translate</Typography>
</Box>
</Box>
);
};

export default LanguageCard;
77 changes: 77 additions & 0 deletions webapp/src/components/ProjectDashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use client';

import { CardGrid } from '@/components/CardGrid';
import { FC } from 'react';
import Link from 'next/link';
import { Box, Typography, useTheme } from '@mui/joy';
import LanguageCard, { LanguageCardProps } from '@/components/LanguageCard';

type ProjectDashboardProps = {
languages: LanguageCardProps[];
messageCount: number;
project: string;
};

const ProjectDashboard: FC<ProjectDashboardProps> = ({
languages,
messageCount,
project,
}) => {
const theme = useTheme();
return (
<Box
alignItems="center"
display="flex"
flexDirection="column"
justifyContent="center"
minHeight="97vh"
rowGap={2}
>
<Box
alignItems="center"
columnGap={1}
display="flex"
flexDirection="row"
width="100%"
>
<Link href="/">
<svg
aria-labelledby="homeTitle"
fill={theme.palette.primary[500]}
viewBox="0 0 576 512"
width={22}
xmlns="http://www.w3.org/2000/svg"
>
<title id="homeTitle">Home</title>
<path d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z" />
</svg>
</Link>
</Box>
<Box
sx={{
alignItems: 'center',
display: 'flex',
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
width: '100%',
}}
>
<CardGrid
heading={
<>
<Typography component="h1">{project}</Typography>
<Typography>{messageCount} messages</Typography>
</>
}
>
{languages.map((language, i) => (
<LanguageCard key={i} {...language} />
))}
</CardGrid>
</Box>
</Box>
);
};

export default ProjectDashboard;

0 comments on commit 01cc6e8

Please sign in to comment.