diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/ProjectPreview/ProjectPreview.module.scss | 87 | ||||
| -rw-r--r-- | src/components/ProjectPreview/ProjectPreview.tsx | 55 | ||||
| -rw-r--r-- | src/components/ProjectsList/ProjectsList.module.scss | 25 | ||||
| -rw-r--r-- | src/components/ProjectsList/ProjectsList.tsx | 21 |
4 files changed, 188 insertions, 0 deletions
diff --git a/src/components/ProjectPreview/ProjectPreview.module.scss b/src/components/ProjectPreview/ProjectPreview.module.scss new file mode 100644 index 0000000..f29dc49 --- /dev/null +++ b/src/components/ProjectPreview/ProjectPreview.module.scss @@ -0,0 +1,87 @@ +@use "@styles/abstracts/functions" as fun; + +.article { + display: flex; + flex-flow: column nowrap; + height: 100%; + padding: var(--spacing-md) var(--spacing-md) var(--spacing-lg); +} + +.cover { + height: fun.convert-px(150); + position: relative; +} + +.title { + flex: 1; + margin: var(--spacing-xs) 0; + background: none; + text-decoration: underline solid transparent 0; + text-shadow: none; + transition: all 0.3s linear 0s; +} + +.body { + margin: 0 0 var(--spacing-xs); +} + +.meta { + display: block; + + &__item { + display: flex; + flex-flow: row wrap; + gap: var(--spacing-2xs); + } +} + +.link { + display: block; + height: 100%; + background: var(--color-bg); + color: inherit; + text-decoration: none; + border: fun.convert-px(3) solid var(--color-primary); + border-radius: fun.convert-px(5); + box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) + var(--color-shadow), + fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2) + var(--color-shadow), + fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4) + var(--color-shadow); + transition: all 0.3s ease-in-out 0s; + + &:hover, + &:focus, + &:active { + color: inherit; + } + + &:hover, + &:focus { + box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) + var(--color-shadow-light), + fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2) + var(--color-shadow-light), + fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4) + var(--color-shadow-light), + fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3) + var(--color-shadow-light); + transform: scale(1.05); + } + + &:focus { + .title { + text-decoration: underline solid var(--color-primary) 0.3ex; + } + } + + &:active { + box-shadow: 0 0 0 0 var(--color-shadow); + transform: scale(0.95); + + .title { + text-decoration: none; + } + } +} diff --git a/src/components/ProjectPreview/ProjectPreview.tsx b/src/components/ProjectPreview/ProjectPreview.tsx new file mode 100644 index 0000000..91969b0 --- /dev/null +++ b/src/components/ProjectPreview/ProjectPreview.tsx @@ -0,0 +1,55 @@ +import { t } from '@lingui/macro'; +import { Project } from '@ts/types/app'; +import { slugify } from '@utils/helpers/slugify'; +import Image from 'next/image'; +import Link from 'next/link'; +import styles from './ProjectPreview.module.scss'; + +const ProjectPreview = ({ project }: { project: Project }) => { + return ( + <Link href={`/projet/${project.slug}`}> + <a className={styles.link}> + <article className={styles.article}> + <header> + {project.cover && ( + <div className={styles.cover}> + <Image + src={project.cover} + layout="fill" + objectFit="contain" + objectPosition="center" + alt={`${project.meta.title} picture`} + /> + </div> + )} + <h2 className={styles.title}>{project.meta.title}</h2> + </header> + <div + className={styles.body} + dangerouslySetInnerHTML={{ __html: project.intro }} + ></div> + <footer> + <dl className={styles.meta}> + {project.meta.license && ( + <div className={styles.meta__item}> + <dt>{t`License:`}</dt> + <dd>{project.meta.license}</dd> + </div> + )} + {project.meta.technologies && ( + <div className={styles.meta__item}> + <dt>{t`Technologies:`}</dt> + {project.meta.technologies.map((techno) => ( + <dd key={slugify(techno)}>{techno}</dd> + ))} + </div> + )} + </dl> + </footer> + </article> + </a> + </Link> + ); +}; + +export default ProjectPreview; diff --git a/src/components/ProjectsList/ProjectsList.module.scss b/src/components/ProjectsList/ProjectsList.module.scss new file mode 100644 index 0000000..6a77aa9 --- /dev/null +++ b/src/components/ProjectsList/ProjectsList.module.scss @@ -0,0 +1,25 @@ +@use "@styles/abstracts/functions" as fun; +@use "@styles/abstracts/placeholders"; + +.list { + --items: 4; + --items-size: 35ch; + + @extend %reset-list; + + display: grid; + grid-template-columns: repeat( + auto-fit, + min(calc(100vw - (var(--spacing-md) * 2)), var(--items-size)) + ); + gap: var(--spacing-sm); + place-content: center; + width: min( + calc(100vw - (var(--spacing-md) * 2)), + calc( + (var(--items-size) * var(--items)) + + (var(--spacing-sm) * (var(--items) - 1)) + ) + ); + margin: var(--spacing-sm) auto 0; +} diff --git a/src/components/ProjectsList/ProjectsList.tsx b/src/components/ProjectsList/ProjectsList.tsx new file mode 100644 index 0000000..609d824 --- /dev/null +++ b/src/components/ProjectsList/ProjectsList.tsx @@ -0,0 +1,21 @@ +import ProjectPreview from '@components/ProjectPreview/ProjectPreview'; +import { Project } from '@ts/types/app'; +import styles from './ProjectsList.module.scss'; + +const ProjectsList = ({ projects }: { projects: Project[] }) => { + const getProjectItems = () => { + return projects.map((project) => { + return project.meta.title ? ( + <li className={styles.item} key={project.id}> + <ProjectPreview project={project} /> + </li> + ) : ( + '' + ); + }); + }; + + return <ul className={styles.list}>{getProjectItems()}</ul>; +}; + +export default ProjectsList; |
