From 138daaa99b47ff18ec4da5bf05ed20ecf9bf2b81 Mon Sep 17 00:00:00 2001 From: Harlon Garcia Date: Tue, 10 Dec 2024 23:18:32 -0300 Subject: [PATCH] Implemented challenge solutions --- .github/workflows/main.yml | 2 +- src/components/Select/index.tsx | 40 +++--- src/components/Sidebar/index.tsx | 2 +- src/components/shared/Avatar/index.tsx | 10 +- src/components/shared/Select/index.tsx | 110 +++++++-------- src/components/shared/UserLink/index.tsx | 40 +++--- src/components/shared/UserLink/styles.ts | 25 ++-- .../Participants/PreviewDemo/index.tsx | 28 ++++ src/pages/Challenges/Participants/index.tsx | 126 ++++++++---------- src/pages/Challenges/Participants/styles.ts | 38 +++--- src/pages/Dashboard/CreateChallenge/index.tsx | 43 +++--- .../Dashboard/partials/Challenges/index.tsx | 15 ++- src/styles/wrapper.ts | 1 + src/translation/languages/en.json | 5 +- src/translation/languages/pt.json | 5 +- tailwind.config.js | 1 + vite.config.ts | 39 +++--- 17 files changed, 283 insertions(+), 247 deletions(-) create mode 100644 src/pages/Challenges/Participants/PreviewDemo/index.tsx diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4651ed3..c4ed09a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [main] + branches: [master] jobs: CI: diff --git a/src/components/Select/index.tsx b/src/components/Select/index.tsx index f7eafe5..0da64cd 100644 --- a/src/components/Select/index.tsx +++ b/src/components/Select/index.tsx @@ -1,25 +1,28 @@ import { ChangeEvent, ComponentProps } from 'react'; +import { useTranslation } from 'react-i18next'; import { NONE } from 'utils/constants'; import './styles.scss'; interface SelectProps extends ComponentProps<'select'> { - cannotBeEmpty?: boolean; - placeholder: string; - label?: string; - value?: string; - onChange: (event: ChangeEvent) => void; - options: { - label: string; - value: string; - disabled?: boolean; - }[]; + onChange: (event: ChangeEvent) => void; + deselectable?: boolean; + error?: string; + placeholder?: string; + label?: string; + value?: string; + options: { + label: string; + value: string; + disabled?: boolean; + }[]; } export const Select = ({ id, - cannotBeEmpty = false, + deselectable = false, + error, placeholder, label, options, @@ -27,10 +30,12 @@ export const Select = ({ onChange, ...rest }: SelectProps) => { + const { t } = useTranslation(); + return (
{label && ( - + )} + {error && ( + {error} + )}
); }; \ No newline at end of file diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx index 3534b84..ba99c7f 100644 --- a/src/components/Sidebar/index.tsx +++ b/src/components/Sidebar/index.tsx @@ -49,7 +49,7 @@ export default function Sidebar({ .findIndex(({ path }) => path === window.location.pathname.split('/')[2]); setActivePage(-1 === pathIndex ? 0 : pathIndex); - }, [activePage]); + }, []); return ( diff --git a/src/components/shared/Avatar/index.tsx b/src/components/shared/Avatar/index.tsx index a3803cf..596b85d 100644 --- a/src/components/shared/Avatar/index.tsx +++ b/src/components/shared/Avatar/index.tsx @@ -1,4 +1,4 @@ -import { twJoin } from 'tailwind-merge'; +import { twJoin, twMerge } from 'tailwind-merge'; import { tv } from 'tailwind-variants'; interface AvatarProps { @@ -6,6 +6,7 @@ interface AvatarProps { name?: string; size?: 'sm' | 'md' | 'lg' | 'xl'; border?: boolean; + className?: string; onClick?: () => void; } @@ -50,6 +51,7 @@ export const Avatar = ({ url, size, border = false, + className = '', onClick = () => {}, }: AvatarProps) => { const getPlaceholder = (text?: string): string => { @@ -62,12 +64,14 @@ export const Avatar = ({ const placeholder = getPlaceholder(name); - const classNames = twJoin(avatar({ size }), + const defaultClasses = twJoin(avatar({ size }), border && 'border-green-800', ); + const classes = twMerge(defaultClasses, className); + return ( -
+
-
- - - - - - - - - - - - {participants.map(({ - id, - name, - image, - githubUrl, - additionalUrl, - labels, - }) => ( - - - - - - - - ))} - -
- {t('pages.challenge_users.table.columns.name')} - - {t('pages.challenge_users.table.columns.github')} - - {t('pages.challenge_users.table.columns.additional_url')} - - {t('pages.challenge_users.table.columns.labels')} -
- - {name} - - - - -
- {labels?.slice(0, 3).map(({ id, title }) => ( - - {title} - - ))} -
-
+
+ {participants.map(({ + id, + name, + image, + labels, + }) => { + + const labelsShown = windowWidth > 778 ? 2 : 1; + + return ( +
+ +
+ + {t('pages.challenge_users.table.columns.name')} + + + {name} + +
+
+ + {t('pages.challenge_users.table.columns.solution')} + + +
+
+ {labels?.slice(0, labelsShown).map(({ id, title }) => ( + + {title} + + ))} +
+
+ ) + })}
); diff --git a/src/pages/Challenges/Participants/styles.ts b/src/pages/Challenges/Participants/styles.ts index bbbfdb4..87fcb9c 100644 --- a/src/pages/Challenges/Participants/styles.ts +++ b/src/pages/Challenges/Participants/styles.ts @@ -2,31 +2,31 @@ import { styled } from 'styles'; import { WrapperWithPadding } from 'styles/wrapper'; const Container = styled(WrapperWithPadding, { - maxWidth: '80rem', - margin: '0 auto', + maxWidth: '80rem', + margin: '0 auto', - '> button': { - display: 'flex', - gap: '0.5rem', - alignItems: 'center', + '> button': { + display: 'flex', + gap: '0.5rem', + alignItems: 'center', - padding: '0.5rem 1rem', - borderRadius: '0.5rem', - backgroundColor: '$secondary', - marginBottom: '2rem', + padding: '0.5rem 1rem', + borderRadius: '0.5rem', + backgroundColor: '$secondary', + marginBottom: '2rem', - '> *': { - transition: 'all 0.3s ease-in-out', - }, + '> *': { + transition: 'all 0.3s ease-in-out', + }, - '&:hover': { - color: '$highlight', + '&:hover': { + color: '$highlight', - '> svg': { - transform: 'translateX(-10%)', - }, + '> svg': { + transform: 'translateX(-10%)', + }, + }, }, - }, }); export { Container } \ No newline at end of file diff --git a/src/pages/Dashboard/CreateChallenge/index.tsx b/src/pages/Dashboard/CreateChallenge/index.tsx index ca5b3cf..cd54926 100644 --- a/src/pages/Dashboard/CreateChallenge/index.tsx +++ b/src/pages/Dashboard/CreateChallenge/index.tsx @@ -6,9 +6,9 @@ import { toast } from 'react-toastify'; import { zodResolver } from '@hookform/resolvers/zod'; import { RichText } from 'components/RichText'; +import { Select } from 'components/Select'; import { Input } from 'components/shared/Input'; import { InputFile } from 'components/shared/InputFile'; -import { Select } from 'components/shared/Select'; import { AuthContext } from 'contexts/AuthContext'; import { challengeStatuses } from 'enums/challengeStatus'; import { t } from 'i18next'; @@ -16,7 +16,6 @@ import { MdOutlineClose } from 'react-icons/md'; import { useCategories } from 'services/category'; import { useCreateChallenge } from 'services/challenge'; import { useTechnologies } from 'services/technology'; -import { NONE } from 'utils/constants'; import * as S from './styles'; import { CreateChallengeSchema, createChallengeSchema } from './validation'; @@ -175,6 +174,12 @@ const CreateChallenge = () => { }; const hydratedCategories = useMemo(() => { + if (0 === categories.length) { + return []; + } + + setValue('categoryId', categories[0].id); + return categories.map(({ id, name }) => ({ key: id, label: name, @@ -188,19 +193,11 @@ const CreateChallenge = () => { return !selectedTechnologies.items.some((tech) => tech.id === id); }); - return [ - { - key: NONE, - label: t('global.select.placeholder'), - value: NONE, - disabled: true, - }, - ...filteredTechnologies.map(({ id, name }) => ({ - key: id, - label: name, - value: id, - })), - ]; + return filteredTechnologies.map(({ id, name }) => ({ + key: id, + label: name, + value: id, + })); }, [technologies, selectedTechnologies.items]); const statuses = useMemo(() => { @@ -209,6 +206,8 @@ const CreateChallenge = () => { .values(challengeStatuses) .filter(({ id }) => !unwantedStatuses.includes(id)); + setValue('status', filteredStatuses[0]?.id); + return filteredStatuses.map(({ id, label }) => ({ key: id, value: id, @@ -243,27 +242,23 @@ const CreateChallenge = () => { label={t('pages.create_challenge.fields.category.label')} error={formErrors.categoryId?.message} options={hydratedCategories} - size={'xl'} - weight={'bold'} + deselectable />

{t('pages.dashboard.challenges.description')}

- + +
diff --git a/src/styles/wrapper.ts b/src/styles/wrapper.ts index ddb6ec4..a063565 100644 --- a/src/styles/wrapper.ts +++ b/src/styles/wrapper.ts @@ -9,6 +9,7 @@ const Wrapper = styled(WrapperDefault, { }); const WrapperWithPadding = styled(WrapperDefault, { + width: '100%', wrapperPadding: '2rem', '@xs': { diff --git a/src/translation/languages/en.json b/src/translation/languages/en.json index 668e32c..6f0f4ee 100644 --- a/src/translation/languages/en.json +++ b/src/translation/languages/en.json @@ -12,6 +12,7 @@ "global.challenges.status.canceled": "Canceled", "global.select.placeholder": "Select", + "global.select.none": "None", "global.translation.change": "Change language", "global.label.yes": "Yes", "global.label.no": "No", @@ -88,9 +89,9 @@ "pages.challenge_users.button.return": "Back to challenge", "pages.challenge_users.table.columns.name": "Name", - "pages.challenge_users.table.columns.github": "Github", - "pages.challenge_users.table.columns.additional_url": "Additional url", + "pages.challenge_users.table.columns.solution": "Demo", "pages.challenge_users.table.columns.labels": "Achievements", + "pages.challenge_users.table.columns.demo": "View demo", "pages.signin.title": "Welcome back!", "pages.signin.description": "Log in to continue practicing and learning", diff --git a/src/translation/languages/pt.json b/src/translation/languages/pt.json index 95fbbf9..bbe8b60 100644 --- a/src/translation/languages/pt.json +++ b/src/translation/languages/pt.json @@ -12,6 +12,7 @@ "global.challenges.status.canceled": "Cancelado", "global.select.placeholder": "Selecionar", + "global.select.none": "Nenhum", "global.translation.change": "Mudar idioma", "global.label.yes": "Sim", "global.label.no": "Não", @@ -88,9 +89,9 @@ "pages.challenge_users.button.return": "Retornar ao desafio", "pages.challenge_users.table.columns.name": "Nome", - "pages.challenge_users.table.columns.github": "Github", - "pages.challenge_users.table.columns.additional_url": "Link adicional", + "pages.challenge_users.table.columns.solution": "Demo", "pages.challenge_users.table.columns.labels": "Conquistas", + "pages.challenge_users.table.columns.demo": "Ver demo", "pages.signin.title": "Bem vindo de volta!", "pages.signin.description": "Faça login para continuar praticando e aprendendo", diff --git a/tailwind.config.js b/tailwind.config.js index f1faacc..38495af 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -43,6 +43,7 @@ export default { '4xl': '132rem', }, screens: { + xs: '400px', '3xl': '1920px', '4xl': '2560px', }, diff --git a/vite.config.ts b/vite.config.ts index 18fc934..03c07c7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,25 +4,24 @@ import tsconfigPaths from 'vite-tsconfig-paths'; // https://vitejs.dev/config/ export default defineConfig({ - css: { - preprocessorOptions: { - scss: { - api: 'modern-compiler', - }, + css: { + preprocessorOptions: { + scss: { + api: 'modern-compiler', + }, + }, + }, + plugins: [ + react(), + tsconfigPaths(), + ], + server: { + port: 5173, + }, + build: { + outDir: 'build', + emptyOutDir: true, + sourcemap: true, + chunkSizeWarningLimit: 1600, }, - - }, - plugins: [ - react(), - tsconfigPaths(), - ], - server: { - port: 5173, - }, - build: { - outDir: 'build', - emptyOutDir: true, - sourcemap: true, - chunkSizeWarningLimit: 1600, - }, })