Remove: <a> tags

This commit is contained in:
Sonny
2023-02-14 19:29:39 +01:00
parent 7754c87d96
commit 1636f9152b
6 changed files with 322 additions and 303 deletions

View File

@@ -1,67 +1,76 @@
import LinkTag from 'next/link'; import LinkTag from "next/link";
import styles from '../../styles/home/categories.module.scss'; import styles from "../../styles/home/categories.module.scss";
import { Category } from '../../types'; import { Category } from "../../types";
import EditSVG from '../../public/icons/edit.svg'; import EditSVG from "../../public/icons/edit.svg";
import RemoveSVG from '../../public/icons/remove.svg'; import RemoveSVG from "../../public/icons/remove.svg";
interface CategoriesProps { interface CategoriesProps {
categories: Category[]; categories: Category[];
categoryActive: Category; categoryActive: Category;
handleSelectCategory: (category: Category) => void; handleSelectCategory: (category: Category) => void;
} }
export default function Categories({ categories, categoryActive, handleSelectCategory }: CategoriesProps) { export default function Categories({
return ( categories,
<div className={`${styles['block-wrapper']} ${styles['categories']}`}> categoryActive,
<h4>Catégories</h4> handleSelectCategory,
<ul className={styles['items']}> }: CategoriesProps) {
{categories.map((category, key) => ( return (
<CategoryItem <div className={`${styles["block-wrapper"]} ${styles["categories"]}`}>
category={category} <h4>Catégories</h4>
categoryActive={categoryActive} <ul className={styles["items"]}>
handleSelectCategory={handleSelectCategory} {categories.map((category, key) => (
key={key} <CategoryItem
/> category={category}
))} categoryActive={categoryActive}
</ul> handleSelectCategory={handleSelectCategory}
</div> key={key}
) />
))}
</ul>
</div>
);
} }
interface CategoryItemProps { interface CategoryItemProps {
category: Category; category: Category;
categoryActive: Category; categoryActive: Category;
handleSelectCategory: (category: Category) => void; handleSelectCategory: (category: Category) => void;
} }
function CategoryItem({ category, categoryActive, handleSelectCategory }: CategoryItemProps): JSX.Element { function CategoryItem({
const className = `${styles['item']} ${category.id === categoryActive.id ? styles['active'] : ''}`; category,
const onClick = () => handleSelectCategory(category); categoryActive,
handleSelectCategory,
}: CategoryItemProps): JSX.Element {
const className = `${styles["item"]} ${
category.id === categoryActive.id ? styles["active"] : ""
}`;
const onClick = () => handleSelectCategory(category);
return ( return (
<li className={className} onClick={onClick}> <li className={className} onClick={onClick}>
<div className={styles['content']}> <div className={styles["content"]}>
<span className={styles['name']}>{category.name}</span> <span className={styles["name"]}>{category.name}</span>
<span className={styles['links-count']}> {category.links.length}</span> <span className={styles["links-count"]}> {category.links.length}</span>
</div> </div>
<MenuOptions id={category.id} /> <MenuOptions id={category.id} />
</li> </li>
) );
} }
function MenuOptions({ id }: { id: number; }): JSX.Element { function MenuOptions({ id }: { id: number }): JSX.Element {
return ( return (
<div className={styles['menu-item']}> <div className={styles["menu-item"]}>
<LinkTag href={`/category/edit/${id}`}> <LinkTag href={`/category/edit/${id}`} className={styles["option-edit"]}>
<a className={styles['option-edit']}> <EditSVG />
<EditSVG /> </LinkTag>
</a> <LinkTag
</LinkTag> href={`/category/remove/${id}`}
<LinkTag href={`/category/remove/${id}`}> className={styles["option-remove"]}
<a className={styles['option-remove']}> >
<RemoveSVG /> <RemoveSVG />
</a> </LinkTag>
</LinkTag> </div>
</div> );
) }
}

View File

@@ -1,36 +1,36 @@
import styles from '../../styles/home/categories.module.scss'; import LinkTag from "next/link";
import { Link } from '../../types';
export default function Favorites({ favorites }: { favorites: Link[]; }) { import { Link } from "../../types";
return (
<div className={`${styles['block-wrapper']} ${styles['favorites']}`}> import styles from "../../styles/home/categories.module.scss";
<h4>Favoris</h4>
<ul className={styles['items']}> export default function Favorites({ favorites }: { favorites: Link[] }) {
{favorites.length === 0 return (
? <NoFavLink /> <div className={`${styles["block-wrapper"]} ${styles["favorites"]}`}>
: favorites.map((link, key) => ( <h4>Favoris</h4>
<LinkFavorite link={link} key={key} /> <ul className={styles["items"]}>
))} {favorites.length === 0 ? (
</ul> <NoFavLink />
</div> ) : (
) favorites.map((link, key) => <LinkFavorite link={link} key={key} />)
)}
</ul>
</div>
);
} }
function NoFavLink(): JSX.Element { function NoFavLink(): JSX.Element {
return ( return <li className={styles["no-fav-link"]}>Aucun favoris</li>;
<li className={styles['no-fav-link']}>
Aucun favoris
</li>
)
} }
function LinkFavorite({ link }: { link: Link; }): JSX.Element { function LinkFavorite({ link }: { link: Link }): JSX.Element {
const { name, url, category } = link; const { name, url, category } = link;
return ( return (
<li className={styles['item']}> <li className={styles["item"]}>
<a href={url} target={'_blank'} rel={'noreferrer'}> <LinkTag href={url} target={"_blank"} rel={"noreferrer"}>
{name}<span className={styles['category']}> - {category.name}</span> {name}
</a> <span className={styles["category"]}> - {category.name}</span>
</li> </LinkTag>
) </li>
} );
}

View File

@@ -1,48 +1,47 @@
import { Session } from 'next-auth'; import { Session } from "next-auth";
import LinkTag from 'next/link'; import LinkTag from "next/link";
import Categories from './Categories'; import Categories from "./Categories";
import Favorites from './Favorites'; import Favorites from "./Favorites";
import UserCard from './UserCard'; import UserCard from "./UserCard";
import styles from '../../styles/home/categories.module.scss'; import { Category, Link } from "../../types";
import { Category, Link } from '../../types';
import styles from "../../styles/home/categories.module.scss";
interface SideMenuProps { interface SideMenuProps {
categories: Category[]; categories: Category[];
favorites: Link[]; favorites: Link[];
handleSelectCategory: (category: Category) => void; handleSelectCategory: (category: Category) => void;
categoryActive: Category; categoryActive: Category;
session: Session; session: Session;
} }
export default function SideMenu({ export default function SideMenu({
categories, categories,
favorites, favorites,
handleSelectCategory, handleSelectCategory,
categoryActive, categoryActive,
session session,
}: SideMenuProps) { }: SideMenuProps) {
return (<div className={styles['categories-wrapper']}> return (
<Favorites favorites={favorites} /> <div className={styles["categories-wrapper"]}>
<Categories <Favorites favorites={favorites} />
categories={categories} <Categories
categoryActive={categoryActive} categories={categories}
handleSelectCategory={handleSelectCategory} categoryActive={categoryActive}
/> handleSelectCategory={handleSelectCategory}
<MenuControls /> />
<UserCard session={session} /> <MenuControls />
</div>); <UserCard session={session} />
</div>
);
} }
function MenuControls() { function MenuControls() {
return ( return (
<div className={styles['controls']}> <div className={styles["controls"]}>
<LinkTag href={'/category/create'}> <LinkTag href={"/category/create"}>Créer categorie</LinkTag>
<a>Créer categorie</a> <LinkTag href={"/link/create"}>Créer lien</LinkTag>
</LinkTag> </div>
<LinkTag href={'/link/create'}> );
<a>Créer lien</a> }
</LinkTag>
</div>
)
}

View File

@@ -1,57 +1,63 @@
import Head from 'next/head'; import Head from "next/head";
import Link from 'next/link'; import Link from "next/link";
import MessageManager from './MessageManager'; import MessageManager from "./MessageManager";
import styles from '../styles/create.module.scss'; import styles from "../styles/create.module.scss";
import { config } from '../config'; import { config } from "../config";
interface FormProps { interface FormProps {
title: string; title: string;
errorMessage?: string; errorMessage?: string;
successMessage?: string; successMessage?: string;
infoMessage?: string; infoMessage?: string;
canSubmit: boolean; canSubmit: boolean;
handleSubmit: (event) => void; handleSubmit: (event) => void;
textBtnConfirm?: string; textBtnConfirm?: string;
classBtnConfirm?: string; classBtnConfirm?: string;
children: any; children: any;
} }
export default function Form({ export default function Form({
title, title,
errorMessage, errorMessage,
successMessage, successMessage,
infoMessage, infoMessage,
canSubmit, canSubmit,
handleSubmit, handleSubmit,
textBtnConfirm = 'Valider', textBtnConfirm = "Valider",
classBtnConfirm = '', classBtnConfirm = "",
children children,
}: FormProps) { }: FormProps) {
return (<> return (
<Head> <>
<title>{config.siteName} {title}</title> <Head>
</Head> <title>
<div className={`App ${styles['create-app']}`}> {config.siteName} {title}
<h2>{title}</h2> </title>
<form onSubmit={handleSubmit}> </Head>
{children} <div className={`App ${styles["create-app"]}`}>
<button type='submit' className={classBtnConfirm} disabled={!canSubmit}> <h2>{title}</h2>
{textBtnConfirm} <form onSubmit={handleSubmit}>
</button> {children}
</form> <button
<Link href='/'> type="submit"
<a> Revenir à l'accueil</a> className={classBtnConfirm}
</Link> disabled={!canSubmit}
<MessageManager >
info={infoMessage} {textBtnConfirm}
error={errorMessage} </button>
success={successMessage} </form>
/> <Link href="/"> Revenir à l'accueil</Link>
</div> <MessageManager
</>) info={infoMessage}
} error={errorMessage}
success={successMessage}
/>
</div>
</>
);
}

View File

@@ -1,95 +1,96 @@
import LinkTag from 'next/link'; import LinkTag from "next/link";
import { Category, Link } from '../../types'; import { Category, Link } from "../../types";
import EditSVG from '../../public/icons/edit.svg'; import EditSVG from "../../public/icons/edit.svg";
import RemoveSVG from '../../public/icons/remove.svg'; import RemoveSVG from "../../public/icons/remove.svg";
import styles from '../../styles/home/links.module.scss'; import styles from "../../styles/home/links.module.scss";
export default function Links({ category }: { category: Category; }) { export default function Links({ category }: { category: Category }) {
if (category === null) { if (category === null) {
return (<div className={styles['no-category']}>
<p>Veuillez séléctionner une categorié</p>
<LinkTag href='/category/create'>
<a>ou en créer une</a>
</LinkTag>
</div>)
}
const { name, links } = category;
if (links.length === 0) {
return (<div className={styles['no-link']}>
<p>Aucun lien pour <b>{category.name}</b></p>
<LinkTag href='/link/create'>
<a>Créer un lien</a>
</LinkTag>
</div>)
}
return (<div className={styles['links-wrapper']}>
<h2>{name}<span className={styles['links-count']}> {links.length}</span></h2>
<ul className={styles['links']} key={Math.random()}>
{links.map((link, key) => (
<LinkItem key={key} link={link} />
))}
</ul>
</div>);
}
function LinkItem({ link }: { link: Link; }) {
const { id, name, url, category } = link;
return ( return (
<li className={styles['link']} key={id}> <div className={styles["no-category"]}>
<a href={url} target={'_blank'} rel={'noreferrer'}> <p>Veuillez séléctionner une categorié</p>
<span className={styles['link-name']}> <LinkTag href="/category/create">ou en créer une</LinkTag>
{name}<span className={styles['link-category']}> {category.name}</span> </div>
</span>
<LinkItemURL url={url} />
</a>
<div className={styles['controls']}>
<LinkTag href={`/link/edit/${id}`}>
<a className={styles['edit']}>
<EditSVG />
</a>
</LinkTag>
<LinkTag href={`/link/remove/${id}`}>
<a className={styles['remove']}>
<RemoveSVG />
</a>
</LinkTag>
</div>
</li>
); );
}
const { name, links } = category;
if (links.length === 0) {
return (
<div className={styles["no-link"]}>
<p>
Aucun lien pour <b>{category.name}</b>
</p>
<LinkTag href="/link/create">Créer un lien</LinkTag>
</div>
);
}
return (
<div className={styles["links-wrapper"]}>
<h2>
{name}
<span className={styles["links-count"]}> {links.length}</span>
</h2>
<ul className={styles["links"]} key={Math.random()}>
{links.map((link, key) => (
<LinkItem key={key} link={link} />
))}
</ul>
</div>
);
} }
function LinkItemURL({ url }: { url: string; }) { function LinkItem({ link }: { link: Link }) {
try { const { id, name, url, category } = link;
const { origin, pathname, search } = new URL(url); return (
let text = ''; <li className={styles["link"]} key={id}>
<LinkTag href={url} target={"_blank"} rel={"noreferrer"}>
<span className={styles["link-name"]}>
{name}
<span className={styles["link-category"]}> {category.name}</span>
</span>
<LinkItemURL url={url} />
</LinkTag>
<div className={styles["controls"]}>
<LinkTag href={`/link/edit/${id}`} className={styles["edit"]}>
<EditSVG />
</LinkTag>
<LinkTag href={`/link/remove/${id}`} className={styles["remove"]}>
<RemoveSVG />
</LinkTag>
</div>
</li>
);
}
if (pathname !== '/') { function LinkItemURL({ url }: { url: string }) {
text += pathname; try {
} const { origin, pathname, search } = new URL(url);
let text = "";
if (search !== '') { if (pathname !== "/") {
if (text === '') { text += pathname;
text += '/';
}
text += search;
}
return (
<span className={styles['link-url']}>
{origin}<span className={styles['url-pathname']}>{text}</span>
</span>
)
} catch (error) {
console.error('error', error);
return (
<span className={styles['link-url']}>
{url}
</span>
)
} }
}
if (search !== "") {
if (text === "") {
text += "/";
}
text += search;
}
return (
<span className={styles["link-url"]}>
{origin}
<span className={styles["url-pathname"]}>{text}</span>
</span>
);
} catch (error) {
console.error("error", error);
return <span className={styles["link-url"]}>{url}</span>;
}
}

View File

@@ -1,58 +1,62 @@
import { getProviders, signIn, useSession } from 'next-auth/react'; import { Provider } from "next-auth/providers";
import { useRouter } from 'next/router'; import { getProviders, signIn, useSession } from "next-auth/react";
import Head from "next/head";
import Link from "next/link";
import { useRouter } from "next/router";
import Link from 'next/link'; import MessageManager from "../components/MessageManager";
import Head from 'next/head'; import { config } from "../config";
import styles from '../styles/login.module.scss'; import styles from "../styles/login.module.scss";
import MessageManager from '../components/MessageManager';
import { config } from '../config'; export default function SignIn({ providers }: { providers: Provider[] }) {
import { Provider } from 'next-auth/providers'; const { data: session, status } = useSession();
const info = useRouter().query?.info as string;
const error = useRouter().query?.error as string;
export default function SignIn({ providers }: { providers: Provider[]; }) { if (status === "loading") {
const { data: session, status } = useSession(); return (
const info = useRouter().query?.info as string; <div className="App" style={{ alignItems: "center" }}>
const error = useRouter().query?.error as string; <p style={{ height: "fit-content" }}>
Chargement de la session en cours
</p>
</div>
);
}
if (status === 'loading') { return (
return ( <>
<div className='App' style={{ alignItems: 'center' }}> <Head>
<p style={{ height: 'fit-content' }}>Chargement de la session en cours</p> <title>{config.siteName} Authentification</title>
</div> </Head>
); <div className="App">
} <div className={styles["wrapper"]}>
<h2>Se connecter</h2>
return (<> <MessageManager error={error} info={info} />
<Head> {session !== null && (
<title>{config.siteName} Authentification</title> <MessageManager info="Vous êtes déjà connecté" />
</Head> )}
<div className='App'> <div className={styles["providers"]}>
<div className={styles['wrapper']}> {Object.values(providers).map(({ name, id }) => (
<h2>Se connecter</h2> <button
<MessageManager key={id}
error={error} onClick={() => signIn(id, { callbackUrl: "/" })}
info={info} disabled={session !== null}
/> >
{session !== null && (<MessageManager info='Vous êtes déjà connecté' />)} Continuer avec {name}
<div className={styles['providers']}> </button>
{Object.values(providers).map(({ name, id }) => ( ))}
<button key={id} onClick={() => signIn(id, { callbackUrl: '/' })} disabled={session !== null}> </div>
Continuer avec {name} <Link href="/"> Revenir à l'accueil</Link>
</button>
))}
</div>
<Link href='/'>
<a> Revenir à l'accueil</a>
</Link>
</div>
</div> </div>
</>); </div>
</>
);
} }
export async function getServerSideProps(context) { export async function getServerSideProps() {
const providers = await getProviders(); const providers = await getProviders();
return { return {
props: { providers } props: { providers },
} };
} }