mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-08 22:53:25 +00:00
Ajout style
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"discord.enabled": false
|
||||||
|
}
|
||||||
@@ -2,30 +2,36 @@ import styles from '../../styles/categories.module.scss';
|
|||||||
|
|
||||||
export default function Categories({ categories, favorites, handleSelectCategory, categoryActive }) {
|
export default function Categories({ categories, favorites, handleSelectCategory, categoryActive }) {
|
||||||
return (<div className={styles['categories-wrapper']}>
|
return (<div className={styles['categories-wrapper']}>
|
||||||
<div className={styles['block-wrapper']}>
|
<div className={`${styles['block-wrapper']} ${styles['favorites']}`}>
|
||||||
<h4>Favoris</h4>
|
<h4>Favoris</h4>
|
||||||
<ul className={styles['favorites']}>
|
<ul className={styles['items']}>
|
||||||
{favorites.map(({ name, category }, key) => {
|
{favorites.map(({ name, link, category }, key) => {
|
||||||
const catName = categories.find(c => c.id === category).name;
|
const catName = categories.find(c => c.id === category).name;
|
||||||
return <li key={key} className={styles['item']}>
|
return <li key={key} className={styles['item']}>
|
||||||
{name} <span className={styles['category']}>- {catName}</span>
|
<a href={link} target={'_blank'} rel={'noreferrer'}>
|
||||||
|
{name} <span className={styles['category']}>- {catName}</span>
|
||||||
|
</a>
|
||||||
</li>;
|
</li>;
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles['block-wrapper']}>
|
<div className={`${styles['block-wrapper']} ${styles['categories']}`}>
|
||||||
<h4>Catégories</h4>
|
<h4>Catégories</h4>
|
||||||
<ul className={styles['categories']}>
|
<ul className={styles['items']}>
|
||||||
{categories.map(({ id, name }, key) => (
|
{categories.map(({ id, name }, key) => {
|
||||||
<li
|
const className = `${styles['item']} ${id === categoryActive ? styles['active'] : ''}`;
|
||||||
key={key}
|
const onClick = () => handleSelectCategory(id);
|
||||||
className={id === categoryActive ? styles['active'] : null}
|
|
||||||
onClick={() => handleSelectCategory(id)}
|
return (
|
||||||
>
|
<li key={key} className={className} onClick={onClick}>
|
||||||
{name} {id === categoryActive ? '(active)' : ''}
|
{name}
|
||||||
</li>
|
</li>
|
||||||
))}
|
)
|
||||||
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={`${styles['block-wrapper']} ${styles['controls']}`}>
|
||||||
|
<button>Se connecter</button>
|
||||||
|
</div>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,11 @@
|
|||||||
import { useEffect, useCallback } from 'react';
|
|
||||||
import { useInView } from 'react-intersection-observer';
|
|
||||||
|
|
||||||
import styles from '../../styles/links.module.scss';
|
import styles from '../../styles/links.module.scss';
|
||||||
|
|
||||||
export default function Link({ category, setCategoryActive, refCategoryActive }) {
|
export default function Link({ link }) {
|
||||||
const { ref, inView } = useInView({ threshold: .5 });
|
|
||||||
const { id, name, links, ref: refCategory } = category;
|
|
||||||
|
|
||||||
useEffect(() => inView ? setCategoryActive(id) : null, [id, inView, setCategoryActive]);
|
|
||||||
|
|
||||||
const setRefs = useCallback((node) => {
|
|
||||||
refCategory.current = node;
|
|
||||||
refCategoryActive.current = node;
|
|
||||||
ref(node);
|
|
||||||
}, [ref, refCategoryActive, refCategory]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles['link-block']} ref={setRefs}>
|
<li className={styles['link']}>
|
||||||
<h2>{name}</h2>
|
<a href={link?.link} target={'_blank'} rel={'noreferrer'}>
|
||||||
<ul className={styles['links']}>
|
<span className={styles['link-name']}>{link?.name}</span> <span className={styles['link-url']}>{link?.link}</span>
|
||||||
{links.map(({ name }, key2) => (
|
</a>
|
||||||
<li key={key2} className={styles['item']}>{name}</li>
|
</li>
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
30
components/Links/LinkBlock.js
Normal file
30
components/Links/LinkBlock.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { useEffect, useCallback } from 'react';
|
||||||
|
import { useInView } from 'react-intersection-observer';
|
||||||
|
|
||||||
|
import Link from './Link';
|
||||||
|
|
||||||
|
import styles from '../../styles/links.module.scss';
|
||||||
|
|
||||||
|
export default function LinkBlock({ category, setCategoryActive, refCategoryActive }) {
|
||||||
|
const { ref, inView } = useInView({ threshold: .5 });
|
||||||
|
const { id, name, links, ref: refCategory } = category;
|
||||||
|
|
||||||
|
useEffect(() => inView ? setCategoryActive(id) : null, [id, inView, setCategoryActive]);
|
||||||
|
|
||||||
|
const setRefs = useCallback((node) => {
|
||||||
|
refCategory.current = node;
|
||||||
|
refCategoryActive.current = node;
|
||||||
|
ref(node);
|
||||||
|
}, [ref, refCategoryActive, refCategory]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles['link-block']} ref={setRefs}>
|
||||||
|
<h2>{name}</h2>
|
||||||
|
<ul className={styles['links']}>
|
||||||
|
{links.map((link, key2) => (
|
||||||
|
<Link key={key2} link={link} />
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import Link from './Link';
|
import LinkBlock from './LinkBlock';
|
||||||
|
|
||||||
import styles from '../../styles/links.module.scss';
|
import styles from '../../styles/links.module.scss';
|
||||||
|
|
||||||
export default function Links({ categories, setCategoryActive, refCategoryActive }) {
|
export default function Links({ categories, setCategoryActive, refCategoryActive }) {
|
||||||
return (<div className={styles['links-wrapper']}>
|
return (<div className={styles['links-wrapper']}>
|
||||||
{categories.map((category, key) => (
|
{categories.map((category, key) => (
|
||||||
<Link
|
<LinkBlock
|
||||||
key={key}
|
key={key}
|
||||||
category={category}
|
category={category}
|
||||||
setCategoryActive={setCategoryActive}
|
setCategoryActive={setCategoryActive}
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ export async function getStaticProps(context) {
|
|||||||
links.push({
|
links.push({
|
||||||
id: y,
|
id: y,
|
||||||
name: 'Lien #' + (y + 1),
|
name: 'Lien #' + (y + 1),
|
||||||
category: i
|
category: i,
|
||||||
|
link: `https://google.com/search?q=${y}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
.categories-wrapper {
|
.categories-wrapper {
|
||||||
border: 1px solid red;
|
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding: 10px;
|
padding: 0 25px 0 10px;
|
||||||
|
border-right: 1px solid #dadce0;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-x: auto;
|
overflow-x: none;
|
||||||
|
|
||||||
& .block-wrapper {
|
& .block-wrapper {
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -16,17 +15,72 @@
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
& h4 {
|
& h4 {
|
||||||
|
user-select: none;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: .85em;
|
font-size: .85em;
|
||||||
color: #dadce0;
|
color: #bbb;
|
||||||
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .favorites .item .category {
|
// List items
|
||||||
color: #dadce0;
|
& .items .item {
|
||||||
}
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #dadce0;
|
||||||
|
border-bottom: 2px solid #dadce0;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
transition: .15s;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #fff;
|
||||||
|
background: #3f88c5;
|
||||||
|
border-color: #3f88c5;
|
||||||
|
}
|
||||||
|
|
||||||
& .categories .active {
|
&:hover:not(.active) {
|
||||||
color: red;
|
color: #3f88c5;
|
||||||
|
border-bottom: 2px solid #3f88c5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Favorites
|
||||||
|
& .block-wrapper.favorites {
|
||||||
|
& .items .item a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .items .item .category {
|
||||||
|
color: #bbb;
|
||||||
|
font-size: .85em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Categories
|
||||||
|
& .block-wrapper.categories {
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
& .items {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
& .item {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
& .block-wrapper.controls {
|
||||||
|
margin-bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,600;1,300;1,600&display=swap');
|
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Rubik:ital,wght@0,400;0,700;1,400;1,700&display=swap");
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -11,7 +11,8 @@ html,
|
|||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: Poppins, sans-serif;
|
color: #111;
|
||||||
|
font-family: "Poppins", sans-serif;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -26,6 +27,28 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, li {
|
ul,
|
||||||
|
li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* width */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #eee;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #3f88c5;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #1e5c8f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
.links-wrapper {
|
.links-wrapper {
|
||||||
border: 1px solid red;
|
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -16,10 +14,43 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
|
|
||||||
|
& h2 {
|
||||||
|
color: #3f88c5;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
& .links {
|
& .links {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& .links .link {
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
color: #3f88c5;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: 1px solid #dadce0;
|
||||||
|
border-bottom: 2px solid #dadce0;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
transition: .15s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-bottom-color: #3f88c5;
|
||||||
|
transform: scale(1.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .link-url {
|
||||||
|
color: #bbb;
|
||||||
|
font-size: .80em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user