aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/Widgets
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-24 19:35:12 +0200
committerGitHub <noreply@github.com>2022-05-24 19:35:12 +0200
commitc85ab5ad43ccf52881ee224672c41ec30021cf48 (patch)
tree8058808d9bfca19383f120c46b34d99ff2f89f63 /src/components/Widgets
parent52404177c07a2aab7fc894362fb3060dff2431a0 (diff)
parent11b9de44a4b2f305a6a484187805e429b2767118 (diff)
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/components/Widgets')
-rw-r--r--src/components/Widgets/CVPreview/CVPreview.module.scss6
-rw-r--r--src/components/Widgets/CVPreview/CVPreview.tsx45
-rw-r--r--src/components/Widgets/RecentPosts/RecentPosts.module.scss109
-rw-r--r--src/components/Widgets/RecentPosts/RecentPosts.tsx78
-rw-r--r--src/components/Widgets/RelatedThematics/RelatedThematics.tsx41
-rw-r--r--src/components/Widgets/RelatedTopics/RelatedTopics.tsx41
-rw-r--r--src/components/Widgets/Sharing/Sharing.module.scss193
-rw-r--r--src/components/Widgets/Sharing/Sharing.tsx238
-rw-r--r--src/components/Widgets/SocialMedia/SocialMedia.module.scss59
-rw-r--r--src/components/Widgets/SocialMedia/SocialMedia.tsx113
-rw-r--r--src/components/Widgets/ThematicsList/ThematicsList.tsx76
-rw-r--r--src/components/Widgets/ToC/ToC.tsx55
-rw-r--r--src/components/Widgets/TopicsList/TopicsList.tsx76
-rw-r--r--src/components/Widgets/index.tsx21
14 files changed, 0 insertions, 1151 deletions
diff --git a/src/components/Widgets/CVPreview/CVPreview.module.scss b/src/components/Widgets/CVPreview/CVPreview.module.scss
deleted file mode 100644
index 6ddd696..0000000
--- a/src/components/Widgets/CVPreview/CVPreview.module.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.preview {
- position: relative;
- width: 100%;
- height: 20rem;
- margin-bottom: var(--spacing-sm);
-}
diff --git a/src/components/Widgets/CVPreview/CVPreview.tsx b/src/components/Widgets/CVPreview/CVPreview.tsx
deleted file mode 100644
index cf6a8fa..0000000
--- a/src/components/Widgets/CVPreview/CVPreview.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { ExpandableWidget } from '@components/WidgetParts';
-import Image from 'next/image';
-import Link from 'next/link';
-import { FormattedMessage } from 'react-intl';
-import styles from './CVPreview.module.scss';
-
-const CVPreview = ({
- title,
- imgSrc,
- pdf,
-}: {
- title: string;
- imgSrc: string;
- pdf: string;
-}) => {
- return (
- <ExpandableWidget title={title} expand={true}>
- <div className={styles.preview}>
- <Image
- src={imgSrc}
- layout="fill"
- objectFit="contain"
- objectPosition="left"
- alt="CV Armand Philippot"
- />
- </div>
- <p>
- <FormattedMessage
- defaultMessage="Download <link>CV in PDF</link>"
- description="CVPreview: download as PDF link"
- id="xC3Khf"
- values={{
- link: (chunks: string) => (
- <Link href={pdf}>
- <a>{chunks}</a>
- </Link>
- ),
- }}
- />
- </p>
- </ExpandableWidget>
- );
-};
-
-export default CVPreview;
diff --git a/src/components/Widgets/RecentPosts/RecentPosts.module.scss b/src/components/Widgets/RecentPosts/RecentPosts.module.scss
deleted file mode 100644
index 1b85265..0000000
--- a/src/components/Widgets/RecentPosts/RecentPosts.module.scss
+++ /dev/null
@@ -1,109 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
- --items: 3;
- --items-size: 25ch;
-
- @extend %reset-list;
-
- display: grid;
- grid-template-columns: repeat(
- auto-fit,
- min(calc(100vw - (var(--spacing-md) * 2)), var(--items-size))
- );
- justify-content: center;
- gap: var(--spacing-sm);
- width: min(
- calc(100vw - (var(--spacing-md) * 2)),
- calc(
- (var(--items-size) * var(--items)) +
- (var(--spacing-sm) * (var(--items) - 1))
- )
- );
- margin-bottom: var(--spacing-md);
-}
-
-.item {
- text-align: center;
-}
-
-.article {
- display: flex;
- flex-flow: column nowrap;
- height: 100%;
- padding: 0 0 var(--spacing-md);
-}
-
-.title {
- flex: 1;
- margin: var(--spacing-sm) 0;
- padding: 0 var(--spacing-md);
- text-decoration: underline solid transparent 0;
- transition: all 0.3s linear 0s;
-}
-
-.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;
- }
- }
-}
-
-.cover {
- width: 100%;
- height: clamp(fun.convert-px(100), 20vw, fun.convert-px(150));
- position: relative;
- border: fun.convert-px(1) solid var(--color-border);
-}
-
-.meta {
- display: block;
- margin: 0;
- padding: 0 var(--spacing-md);
- font-size: var(--font-size-sm);
-}
diff --git a/src/components/Widgets/RecentPosts/RecentPosts.tsx b/src/components/Widgets/RecentPosts/RecentPosts.tsx
deleted file mode 100644
index 11d8558..0000000
--- a/src/components/Widgets/RecentPosts/RecentPosts.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { getPublishedPosts } from '@services/graphql/queries';
-import { ArticlePreview } from '@ts/types/articles';
-import { PostsList } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { getFormattedDate } from '@utils/helpers/format';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-import styles from './RecentPosts.module.scss';
-
-const RecentPosts = ({ posts }: { posts: PostsList }) => {
- const intl = useIntl();
- const { data, error } = useSWR<PostsList>(
- '/recent-posts',
- () => getPublishedPosts({ first: 3 }),
- { fallbackData: posts }
- );
- const router = useRouter();
- const locale = router.locale ? router.locale : settings.locales.defaultLocale;
-
- const getPost = (post: ArticlePreview) => {
- return (
- <li key={post.id} className={styles.item}>
- <Link href={`/article/${post.slug}`}>
- <a className={styles.link}>
- <article className={styles.article}>
- {post.featuredImage &&
- Object.keys(post.featuredImage).length > 0 && (
- <div className={styles.cover}>
- <Image
- src={post.featuredImage.sourceUrl}
- alt={post.featuredImage.altText}
- layout="fill"
- objectFit="contain"
- />
- </div>
- )}
- <h3 className={styles.title}>{post.title}</h3>
- <dl className={styles.meta}>
- <dt>
- {intl.formatMessage({
- defaultMessage: 'Published on:',
- description: 'RecentPosts: publication date label',
- id: '1h+N2z',
- })}
- </dt>
- <dd>
- <time dateTime={post.dates.publication}>
- {getFormattedDate(post.dates.publication, locale)}
- </time>
- </dd>
- </dl>
- </article>
- </a>
- </Link>
- </li>
- );
- };
-
- const getPostsItems = () => {
- if (error)
- return intl.formatMessage({
- defaultMessage: 'Failed to load.',
- description: 'RecentPosts: failed to load text',
- id: 'iyEh0R',
- });
- if (!data) return <Spinner />;
-
- return data.posts.map((post) => getPost(post));
- };
-
- return <ul className={styles.list}>{getPostsItems()}</ul>;
-};
-
-export default RecentPosts;
diff --git a/src/components/Widgets/RelatedThematics/RelatedThematics.tsx b/src/components/Widgets/RelatedThematics/RelatedThematics.tsx
deleted file mode 100644
index a66de82..0000000
--- a/src/components/Widgets/RelatedThematics/RelatedThematics.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-
-const RelatedThematics = ({ thematics }: { thematics: ThematicPreview[] }) => {
- const intl = useIntl();
- const sortedThematics = [...thematics].sort((a, b) =>
- a.title.localeCompare(b.title)
- );
-
- const thematicsList = sortedThematics.map((thematic) => {
- return (
- <li key={thematic.databaseId}>
- <Link href={`/thematique/${thematic.slug}`}>
- <a>{thematic.title}</a>
- </Link>
- </li>
- );
- });
-
- return (
- <ExpandableWidget
- expand={true}
- title={intl.formatMessage(
- {
- defaultMessage:
- '{thematicsCount, plural, =0 {Related thematics} one {Related thematic} other {Related thematics}}',
- description: 'RelatedThematics: widget title',
- id: 'qXQETZ',
- },
- { thematicsCount: thematics.length }
- )}
- withBorders={true}
- >
- <List items={thematicsList} />
- </ExpandableWidget>
- );
-};
-
-export default RelatedThematics;
diff --git a/src/components/Widgets/RelatedTopics/RelatedTopics.tsx b/src/components/Widgets/RelatedTopics/RelatedTopics.tsx
deleted file mode 100644
index 992173d..0000000
--- a/src/components/Widgets/RelatedTopics/RelatedTopics.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-
-const RelatedTopics = ({ topics }: { topics: TopicPreview[] }) => {
- const intl = useIntl();
- const sortedTopics = [...topics].sort((a, b) =>
- a.title.localeCompare(b.title)
- );
-
- const topicsList = sortedTopics.map((topic) => {
- return (
- <li key={topic.databaseId}>
- <Link href={`/sujet/${topic.slug}`}>
- <a>{topic.title}</a>
- </Link>
- </li>
- );
- });
-
- return (
- <ExpandableWidget
- expand={true}
- title={intl.formatMessage(
- {
- defaultMessage:
- '{topicsCount, plural, =0 {Related topics} one {Related topic} other {Related topics}}',
- description: 'RelatedTopics: widget title',
- id: 'w/lPUh',
- },
- { topicsCount: topicsList.length }
- )}
- withBorders={true}
- >
- <List items={topicsList} />
- </ExpandableWidget>
- );
-};
-
-export default RelatedTopics;
diff --git a/src/components/Widgets/Sharing/Sharing.module.scss b/src/components/Widgets/Sharing/Sharing.module.scss
deleted file mode 100644
index ada3e2f..0000000
--- a/src/components/Widgets/Sharing/Sharing.module.scss
+++ /dev/null
@@ -1,193 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.list {
- @extend %flex-list;
-
- gap: var(--spacing-sm);
- padding: var(--spacing-2xs) 0 0 var(--spacing-2xs);
-
- @include mix.media("screen") {
- @include mix.dimensions("md") {
- gap: var(--spacing-xs);
- width: min-content;
- }
- }
-}
-
-.link {
- display: flex;
- flex-flow: row nowrap;
- align-items: center;
- padding: var(--spacing-2xs) var(--spacing-xs);
- border-radius: fun.convert-px(3);
- font-weight: 600;
- text-decoration: none;
- transition: all 0.3s ease-in-out 0s;
-
- &:hover,
- &:focus {
- color: hsl(0, 0%, 100%);
- transform: translateX(#{fun.convert-px(-3)})
- translateY(#{fun.convert-px(-3)});
- }
-
- &:active {
- color: hsl(0, 0%, 100%);
- transform: translateX(#{fun.convert-px(2)}) translateY(#{fun.convert-px(2)});
-
- @include mix.motion("reduce") {
- transform: none;
- }
- }
-
- &::before {
- display: block;
- background-repeat: no-repeat;
- content: "";
- filter: drop-shadow(
- #{fun.convert-px(1)} #{fun.convert-px(1)} #{fun.convert-px(1)} hsl(0, 0%, 0%)
- );
- width: fun.convert-px(30);
- height: fun.convert-px(30);
- }
-
- &--diaspora {
- background: hsl(0, 0%, 13%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(0, 0%, 3%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0 hsl(0, 0%, 3%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0 hsl(0, 0%, 3%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path style="fill:#ffffff;" d="M15.257 21.928l-2.33-3.255c-.622-.87-1.128-1.549-1.155-1.55-.027 0-1.007 1.317-2.317 3.115-1.248 1.713-2.28 3.115-2.292 3.115-.035 0-4.5-3.145-4.51-3.178-.006-.016 1.003-1.497 2.242-3.292 1.239-1.794 2.252-3.29 2.252-3.325 0-.056-.401-.197-3.55-1.247a1604.93 1604.93 0 01-3.593-1.2c-.033-.013.153-.635.79-2.648.46-1.446.845-2.642.857-2.656.013-.015 1.71.528 3.772 1.207 2.062.678 3.766 1.233 3.787 1.233.021 0 .045-.032.053-.07.008-.039.026-1.794.04-3.902.013-2.107.036-3.848.05-3.87.02-.03.599-.038 2.725-.038 1.485 0 2.716.01 2.735.023.023.016.064 1.175.132 3.776.112 4.273.115 4.33.183 4.33.026 0 1.66-.547 3.631-1.216 1.97-.668 3.593-1.204 3.605-1.191.04.045 1.656 5.307 1.636 5.327-.011.01-1.656.574-3.655 1.252-2.75.932-3.638 1.244-3.645 1.284-.006.029.94 1.442 2.143 3.202 1.184 1.733 2.148 3.164 2.143 3.18-.012.036-4.442 3.299-4.48 3.299-.015 0-.577-.767-1.249-1.705z"/></svg>'
- ));
- }
- }
-
- &--email {
- background: hsl(0, 0%, 44%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(0, 0%, 34%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0 hsl(0, 0%, 34%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0 hsl(0, 0%, 34%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M15.909 12.123L24 17.238V6.792zM0 6.792v10.446l8.091-5.115zM22.5 3.75h-21c-.748 0-1.343.558-1.455 1.276L12 12.904l11.955-7.877c-.112-.718-.706-1.276-1.455-1.276zm-7.965 9.279l-2.123 1.398a.75.75 0 01-.825 0l-2.122-1.4-9.417 5.957c.116.712.707 1.266 1.452 1.266h21c.746 0 1.337-.553 1.452-1.266z"/></svg>'
- ));
- }
- }
-
- &--facebook {
- background: hsl(214, 89%, 52%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(214, 89%, 42%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
- hsl(214, 89%, 42%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
- hsl(214, 89%, 42%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'
- ));
- }
- }
-
- &--journal-du-hacker {
- background: hsl(210, 24%, 51%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(210, 24%, 41%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
- hsl(210, 24%, 41%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
- hsl(210, 24%, 41%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M17.822 23.297a6.644 6.644 0 00-.654.032c-1.104.1-2.451-.378-3.244-1.15a3.223 3.223 0 01-.52-.739c-.209-.425-.22-.489-.211-1.178a8.174 8.174 0 01.19-1.585c.243-1.151.155-1.449-.514-1.737-.4-.172-.632-.135-1 .16-.268.215-.28.463-.07 1.532.298 1.526.286 2.238-.05 2.907-.28.56-.443.703-1.287 1.133-1.005.513-1.461.638-2.332.638-.73 0-1.014-.082-1.276-.366-.134-.145-.148-.2-.085-.32.099-.184.329-.3.959-.488.277-.082.604-.236.727-.341.123-.105.329-.265.457-.354.32-.222.562-.761.563-1.254 0-.331-.188-1.034-.45-1.676-.138-.338-.38.085-.38.666 0 .434-.673 1.569-.93 1.569-.048 0-.288.101-.532.225-.43.219-.47.225-1.31.225-.815 0-.889-.011-1.235-.194-.42-.22-.902-.694-1.094-1.073a2.752 2.752 0 00-.227-.377c-.083-.102-.08-.143.018-.293.206-.314.473-.317 1.186-.011.583.25 1.22.215 1.582-.086.168-.139.325-.697.342-1.217.02-.598-.049-.66-.596-.528-.86.206-1.762-.084-2.76-.887-.916-.739-1.362-.845-2.241-.538-.262.092-.51.153-.552.137-.042-.016-.134-.136-.204-.268-.118-.218-.12-.252-.02-.403.156-.24.714-.573 1.185-.708.297-.086.588-.11 1.076-.09.655.026.687.035 1.567.458.54.259.99.43 1.127.43.27 0 1.014-.37 1.159-.577.167-.238.124-.34-.322-.776-1.19-1.16-1.943-2.608-2.24-4.31-.124-.702-.14-1.888-.035-2.483.116-.656.677-2.273.915-2.64.385-.59 1.823-1.965 2.585-2.469C9.187.905 11.43.395 13.715.785c2.457.42 4.507 1.61 5.849 3.394 1.062 1.414 1.554 2.859 1.553 4.57 0 1.778-.497 3.238-1.599 4.693a6.207 6.207 0 00-.34.476c0 .013.205.12.456.238.737.345 1.169.844 1.726 1.994.256.527.531 1.031.613 1.12.225.247.614.42 1.099.49.588.085.804.178.9.388.109.24-.111.55-.402.563-.11.005-.394.033-.63.062-.887.107-1.851-.251-2.416-.898-.17-.193-.503-.616-.74-.939-.455-.616-.818-.922-1.054-.888-.117.017-.14.066-.127.28.008.142.068.34.133.438.09.137.127.412.161 1.196.05 1.153.147 1.458.55 1.726.306.204.552.198 1.11-.025.581-.233.923-.238 1.159-.018.243.227.2.637-.11 1.026-.33.419-1.338.899-2.001.954-1.194.1-2.371-.602-2.828-1.686-.062-.147-.197-.61-.301-1.03-.12-.486-.221-.762-.28-.762-.109 0-.263.401-.27.705-.003.12-.056.417-.118.657-.328 1.282.307 2.309 1.66 2.684.657.182.808.299.808.623 0 .319-.165.494-.454.481z"/></svg>'
- ));
- }
- }
-
- &--linkedin {
- background: hsl(210, 90%, 40%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(210, 90%, 30%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
- hsl(210, 90%, 30%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
- hsl(210, 90%, 30%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path style="fill:#ffffff;" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'
- ));
- }
- }
-
- &--twitter {
- background: hsl(203, 89%, 53%);
- box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(203, 89%, 43%);
-
- &:hover,
- &:focus {
- box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
- hsl(203, 89%, 43%);
- }
-
- &:active {
- box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
- hsl(203, 89%, 43%);
- }
-
- &::before {
- background-image: url(fun.encode-svg(
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>'
- ));
- }
- }
-}
-
-:global {
- [data-theme="dark"] {
- :local {
- .link {
- filter: brightness(0.85) contrast(1.1);
- }
- }
- }
-}
diff --git a/src/components/Widgets/Sharing/Sharing.tsx b/src/components/Widgets/Sharing/Sharing.tsx
deleted file mode 100644
index 45fe3ce..0000000
--- a/src/components/Widgets/Sharing/Sharing.tsx
+++ /dev/null
@@ -1,238 +0,0 @@
-import { ExpandableWidget } from '@components/WidgetParts';
-import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './Sharing.module.scss';
-
-type Parameters = {
- content: string;
- image: string;
- title: string;
- url: string;
-};
-
-type Website = {
- id: string;
- name: string;
- parameters: Parameters;
- url: string;
-};
-
-const Sharing = ({ excerpt, title }: { excerpt: string; title: string }) => {
- const intl = useIntl();
- const [pageExcerpt, setPageExcerpt] = useState('');
- const [pageUrl, setPageUrl] = useState('');
- const [domainName, setDomainName] = useState('');
- const router = useRouter();
-
- useEffect(() => {
- const divEl = document.createElement('div');
- divEl.innerHTML = excerpt;
- const cleanExcerpt = divEl.textContent!;
- setPageExcerpt(cleanExcerpt);
- }, [excerpt]);
-
- useEffect(() => {
- const { protocol, hostname, port } = window.location;
- const currentPort = port ? `:${port}` : '';
- const fullUrl = `${protocol}//${hostname}${currentPort}${router.asPath}`;
-
- setDomainName(hostname);
- setPageUrl(fullUrl);
- }, [router.asPath]);
-
- const getSharingUrl = (website: Website): string => {
- const { id, parameters, url } = website;
- let sharingUrl = `${url}?`;
- let count = 0;
-
- for (const [key, value] of Object.entries(parameters)) {
- if (!value) continue;
-
- sharingUrl += count > 0 ? `&${value}=` : `${value}=`;
-
- switch (key) {
- case 'content':
- if (id === 'email') {
- const intro = intl.formatMessage({
- defaultMessage: 'Introduction:',
- description: 'Sharing: email content prefix',
- id: 'yfgMcl',
- });
- const readMore = intl.formatMessage({
- defaultMessage: 'Read more here:',
- description: 'Sharing: content link prefix',
- id: 'UsQske',
- });
- const body = `${intro}\n\n"${pageExcerpt}"\n\n${readMore} ${pageUrl}`;
- sharingUrl += encodeURI(body);
- } else {
- sharingUrl += encodeURI(pageExcerpt);
- }
- break;
- case 'title':
- const prefix =
- id === 'email'
- ? intl.formatMessage(
- {
- defaultMessage: 'Seen on {domainName}:',
- description: 'Sharing: seen on text',
- id: 'eUXMG4',
- },
- { domainName }
- )
- : '';
- sharingUrl += encodeURI(`${prefix} ${title}`);
- break;
- case 'url':
- sharingUrl += encodeURI(pageUrl);
- break;
- default:
- break;
- }
-
- count++;
- }
-
- return sharingUrl;
- };
-
- const websites = [
- {
- id: 'diaspora',
- name: intl.formatMessage({
- defaultMessage: 'Diaspora',
- description: 'Sharing: Diaspora',
- id: 'Dhow1m',
- }),
- parameters: {
- content: '',
- image: '',
- title: 'title',
- url: 'url',
- },
- url: 'https://share.diasporafoundation.org/',
- },
- {
- id: 'facebook',
- name: intl.formatMessage({
- defaultMessage: 'Facebook',
- description: 'Sharing: Facebook',
- id: '7iiaRx',
- }),
- parameters: {
- content: '',
- image: '',
- title: '',
- url: 'u',
- },
- url: 'https://www.facebook.com/sharer/sharer.php',
- },
- {
- id: 'linkedin',
- name: intl.formatMessage({
- defaultMessage: 'LinkedIn',
- description: 'Sharing: LinkedIn',
- id: 'csCQQk',
- }),
- parameters: {
- content: '',
- image: '',
- title: '',
- url: 'url',
- },
- url: 'https://www.linkedin.com/sharing/share-offsite/',
- },
- {
- id: 'twitter',
- name: intl.formatMessage({
- defaultMessage: 'Twitter',
- description: 'Sharing: Twitter',
- id: 'WjVBnY',
- }),
- parameters: {
- content: '',
- image: '',
- title: 'text',
- url: 'url',
- },
- url: 'https://twitter.com/intent/tweet',
- },
- {
- id: 'journal-du-hacker',
- name: intl.formatMessage({
- defaultMessage: 'Journal du hacker',
- description: 'Sharing: Journal du hacker',
- id: 'P0I+Xm',
- }),
- parameters: {
- content: '',
- image: '',
- title: 'title',
- url: 'url',
- },
- url: 'https://www.journalduhacker.net/stories/new',
- },
- {
- id: 'email',
- name: intl.formatMessage({
- defaultMessage: 'Email',
- description: 'Sharing: Email',
- id: 'lKZm9t',
- }),
- parameters: {
- content: 'body',
- image: '',
- title: 'subject',
- url: '',
- },
- url: 'mailto:',
- },
- ];
-
- const getItems = () => {
- return websites.map((website) => {
- const { id, name } = website;
- const sharingUrl = getSharingUrl(website);
- const linkModifier = `link--${id}`;
-
- return (
- <li key={id}>
- <a
- href={sharingUrl}
- title={name}
- className={`${styles.link} ${styles[linkModifier]}`}
- >
- <span className="screen-reader-text">
- {intl.formatMessage(
- {
- defaultMessage: 'Share on {name}',
- description: 'Sharing: share on social network text',
- id: 'ureXFw',
- },
- { name }
- )}
- </span>
- </a>
- </li>
- );
- });
- };
-
- return (
- <ExpandableWidget
- title={intl.formatMessage({
- defaultMessage: 'Share',
- description: 'Sharing: widget title',
- id: 'q3U6uI',
- })}
- expand={true}
- >
- <ul className={`${styles.list} ${styles['list--sharing']}`}>
- {getItems()}
- </ul>
- </ExpandableWidget>
- );
-};
-
-export default Sharing;
diff --git a/src/components/Widgets/SocialMedia/SocialMedia.module.scss b/src/components/Widgets/SocialMedia/SocialMedia.module.scss
deleted file mode 100644
index 2ef34bf..0000000
--- a/src/components/Widgets/SocialMedia/SocialMedia.module.scss
+++ /dev/null
@@ -1,59 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
- @extend %flex-list;
-
- flex: 0 0 100%;
- gap: var(--spacing-xs);
- align-items: center;
- padding: var(--spacing-2xs) 0 0 var(--spacing-2xs);
-}
-
-.link {
- display: block;
- width: 3em;
- height: 3em;
- background: none;
- 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(-1)
- var(--color-shadow),
- fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3)
- var(--color-shadow),
- 0 0 0 0 var(--color-shadow);
- transition: all 0.3s linear 0s;
-
- &:hover,
- &:focus {
- box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
- var(--color-shadow),
- fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1)
- var(--color-shadow-light),
- fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4)
- var(--color-shadow-light),
- fun.convert-px(6) fun.convert-px(6) fun.convert-px(10) fun.convert-px(-3)
- var(--color-shadow);
- transform: scale(1.15);
- }
-
- &:focus {
- outline: var(--color-primary) dashed fun.convert-px(2);
- }
-
- &:active {
- box-shadow: 0 0 0 0 var(--color-shadow);
- outline: none;
- transform: scale(0.9);
- }
-}
-
-:global {
- [data-theme="dark"] {
- :local {
- .icon {
- filter: brightness(0.85) contrast(1.1);
- }
- }
- }
-}
diff --git a/src/components/Widgets/SocialMedia/SocialMedia.tsx b/src/components/Widgets/SocialMedia/SocialMedia.tsx
deleted file mode 100644
index decf657..0000000
--- a/src/components/Widgets/SocialMedia/SocialMedia.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import GithubIcon from '@assets/images/social-media/github.svg';
-import GitlabIcon from '@assets/images/social-media/gitlab.svg';
-import LinkedInIcon from '@assets/images/social-media/linkedin.svg';
-import TwitterIcon from '@assets/images/social-media/twitter.svg';
-import styles from './SocialMedia.module.scss';
-import { ExpandableWidget } from '@components/WidgetParts';
-import { useIntl } from 'react-intl';
-
-const SocialMedia = ({
- title,
- github = false,
- gitlab = false,
- linkedin = false,
- twitter = false,
-}: {
- title: string;
- github?: boolean;
- gitlab?: boolean;
- linkedin?: boolean;
- twitter?: boolean;
-}) => {
- const intl = useIntl();
-
- const websites = [
- {
- id: 'github',
- name: intl.formatMessage({
- defaultMessage: 'Github',
- description: 'SocialMedia: Github',
- id: 'SWjj4l',
- }),
- url: 'https://github.com/ArmandPhilippot',
- },
- {
- id: 'gitlab',
- name: intl.formatMessage({
- defaultMessage: 'Gitlab',
- description: 'SocialMedia: Gitlab',
- id: 'obmlFh',
- }),
- url: 'https://gitlab.com/ArmandPhilippot',
- },
- {
- id: 'linkedin',
- name: intl.formatMessage({
- defaultMessage: 'LinkedIn',
- description: 'SocialMedia: LinkedIn',
- id: 'VbcHZ4',
- }),
- url: 'https://www.linkedin.com/in/armandphilippot',
- },
- {
- id: 'twitter',
- name: intl.formatMessage({
- defaultMessage: 'Twitter',
- description: 'SocialMedia: Twitter',
- id: 'IPs/Ck',
- }),
- url: 'https://twitter.com/ArmandPhilippot',
- },
- ];
-
- const getIcon = (id: string) => {
- switch (id) {
- case 'github':
- return <GithubIcon className={styles.icon} />;
- case 'gitlab':
- return <GitlabIcon className={styles.icon} />;
- case 'linkedin':
- return <LinkedInIcon className={styles.icon} />;
- case 'twitter':
- return <TwitterIcon className={styles.icon} />;
- default:
- break;
- }
- };
-
- const shouldDisplayLink = (id: string) => {
- switch (id) {
- case 'github':
- return github;
- case 'gitlab':
- return gitlab;
- case 'linkedin':
- return linkedin;
- case 'twitter':
- return twitter;
- default:
- break;
- }
- };
-
- const items = websites.map((website) => {
- return shouldDisplayLink(website.id) ? (
- <li key={website.id}>
- <a href={website.url} className={styles.link}>
- {getIcon(website.id)}
- <span className="screen-reader-text">{website.name}</span>
- </a>
- </li>
- ) : (
- ''
- );
- });
-
- return (
- <ExpandableWidget title={title} expand={true}>
- <ul className={styles.list}>{items}</ul>
- </ExpandableWidget>
- );
-};
-
-export default SocialMedia;
diff --git a/src/components/Widgets/ThematicsList/ThematicsList.tsx b/src/components/Widgets/ThematicsList/ThematicsList.tsx
deleted file mode 100644
index 51254ee..0000000
--- a/src/components/Widgets/ThematicsList/ThematicsList.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { getAllThematics } from '@services/graphql/queries';
-import { TitleLevel } from '@ts/types/app';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-
-const ThematicsList = ({
- title,
- titleLevel,
- initialData,
-}: {
- title: string;
- titleLevel?: TitleLevel;
- initialData?: ThematicPreview[];
-}) => {
- const intl = useIntl();
- const router = useRouter();
- const isThematic = () => router.asPath.includes('/thematique/');
- const currentThematicSlug = isThematic()
- ? router.asPath.replace('/thematique/', '')
- : '';
-
- const { data, error } = useSWR('/api/thematics', getAllThematics, {
- fallbackData: initialData,
- });
-
- const getList = () => {
- if (error)
- return (
- <ul>
- {intl.formatMessage({
- defaultMessage: 'Failed to load.',
- description: 'ThematicsList: failed to load text',
- id: 'PxMDzL',
- })}
- </ul>
- );
- if (!data)
- return (
- <ul>
- <Spinner />
- </ul>
- );
-
- const thematics = data.map((thematic) => {
- return currentThematicSlug !== thematic.slug ? (
- <li key={thematic.databaseId}>
- <Link href={`/thematique/${thematic.slug}`}>
- <a>{thematic.title}</a>
- </Link>
- </li>
- ) : (
- ''
- );
- });
-
- return <List items={thematics} />;
- };
-
- return (
- <ExpandableWidget
- title={title}
- titleLevel={titleLevel}
- withBorders={true}
- expand={true}
- >
- {getList()}
- </ExpandableWidget>
- );
-};
-
-export default ThematicsList;
diff --git a/src/components/Widgets/ToC/ToC.tsx b/src/components/Widgets/ToC/ToC.tsx
deleted file mode 100644
index 3f759db..0000000
--- a/src/components/Widgets/ToC/ToC.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { ExpandableWidget, OrderedList } from '@components/WidgetParts';
-import { Heading } from '@ts/types/app';
-import useHeadingsTree from '@utils/hooks/useHeadingsTree';
-import { FormattedMessage, useIntl } from 'react-intl';
-
-const ToC = () => {
- const intl = useIntl();
- const headingsTree = useHeadingsTree('article');
- const title = intl.formatMessage({
- defaultMessage: 'Table of contents',
- description: 'ToC: widget title',
- id: 'Zg4L7U',
- });
-
- const getItems = (headings: Heading[]) => {
- return headings.map((heading) => {
- return (
- <li key={heading.id}>
- <a href={`#${heading.id}`}>
- <FormattedMessage
- defaultMessage="<a11y>Jump to </a11y>{title}"
- description="ToC: link"
- id="GgIWnN"
- values={{
- title: heading.title,
- a11y: (chunks: string) => (
- <span className="screen-reader-text">{chunks}</span>
- ),
- }}
- />
- </a>
- {heading.children.length > 0 && (
- <OrderedList items={getItems(heading.children)} />
- )}
- </li>
- );
- });
- };
-
- return (
- <ExpandableWidget title={title} kind="toc" expand={true} withBorders={true}>
- <noscript>
- {intl.formatMessage({
- defaultMessage:
- 'Javascript is required to use the table of contents.',
- description: 'ToC: noscript tag',
- id: 'RZzx/4',
- })}
- </noscript>
- <OrderedList items={getItems(headingsTree)} />
- </ExpandableWidget>
- );
-};
-
-export default ToC;
diff --git a/src/components/Widgets/TopicsList/TopicsList.tsx b/src/components/Widgets/TopicsList/TopicsList.tsx
deleted file mode 100644
index 7bc7d70..0000000
--- a/src/components/Widgets/TopicsList/TopicsList.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { getAllTopics } from '@services/graphql/queries';
-import { TitleLevel } from '@ts/types/app';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-
-const TopicsList = ({
- title,
- titleLevel,
- initialData,
-}: {
- title: string;
- titleLevel?: TitleLevel;
- initialData?: TopicPreview[];
-}) => {
- const intl = useIntl();
- const router = useRouter();
- const isTopic = () => router.asPath.includes('/sujet/');
- const currentTopicSlug = isTopic()
- ? router.asPath.replace('/sujet/', '')
- : '';
-
- const { data, error } = useSWR('/api/topics', getAllTopics, {
- fallbackData: initialData,
- });
-
- const getList = () => {
- if (error)
- return (
- <ul>
- {intl.formatMessage({
- defaultMessage: 'Failed to load.',
- description: 'TopicsList: failed to load text',
- id: '00Pf5p',
- })}
- </ul>
- );
- if (!data)
- return (
- <ul>
- <Spinner />
- </ul>
- );
-
- const topics = data.map((topic) => {
- return currentTopicSlug !== topic.slug ? (
- <li key={topic.databaseId}>
- <Link href={`/sujet/${topic.slug}`}>
- <a>{topic.title}</a>
- </Link>
- </li>
- ) : (
- ''
- );
- });
-
- return <List items={topics} />;
- };
-
- return (
- <ExpandableWidget
- title={title}
- titleLevel={titleLevel}
- withBorders={true}
- expand={true}
- >
- {getList()}
- </ExpandableWidget>
- );
-};
-
-export default TopicsList;
diff --git a/src/components/Widgets/index.tsx b/src/components/Widgets/index.tsx
deleted file mode 100644
index 8354449..0000000
--- a/src/components/Widgets/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import CVPreview from './CVPreview/CVPreview';
-import RecentPosts from './RecentPosts/RecentPosts';
-import RelatedThematics from './RelatedThematics/RelatedThematics';
-import RelatedTopics from './RelatedTopics/RelatedTopics';
-import Sharing from './Sharing/Sharing';
-import SocialMedia from './SocialMedia/SocialMedia';
-import ThematicsList from './ThematicsList/ThematicsList';
-import ToC from './ToC/ToC';
-import TopicsList from './TopicsList/TopicsList';
-
-export {
- CVPreview,
- RecentPosts,
- RelatedThematics,
- RelatedTopics,
- Sharing,
- SocialMedia,
- ThematicsList,
- ToC,
- TopicsList,
-};