feat; add quick actions + change icons

This commit is contained in:
Sonny
2023-04-27 00:58:34 +02:00
parent 35a65e5cce
commit 74191b9134
9 changed files with 180 additions and 57 deletions

View File

@@ -1,52 +1,31 @@
import LinkTag from "next/link";
import { useState } from "react";
import {
AiFillDelete,
AiFillEdit,
AiFillStar,
AiOutlineStar,
} from "react-icons/ai";
import { AiFillStar } from "react-icons/ai";
import { Link } from "types";
import EditItem from "components/QuickActions/EditItem";
import FavoriteItem from "components/QuickActions/FavoriteItem";
import RemoveItem from "components/QuickActions/RemoveItem";
import LinkFavicon from "./LinkFavicon";
import styles from "./links.module.scss";
export default function LinkItem({ link }: { link: Link }) {
const { id, name, url, favorite } = link;
const [isFavorite, setFavorite] = useState(favorite);
return (
<li className={styles["link"]} key={id}>
<LinkFavicon url={url} />
<LinkTag href={url} target={"_blank"} rel={"noreferrer"}>
<span className={styles["link-name"]}>
{name} {isFavorite && <AiFillStar color="#ffc107" />}
{name} {favorite && <AiFillStar color="#ffc107" />}
</span>
<LinkItemURL url={url} />
</LinkTag>
<div className={styles["controls"]}>
<div onClick={() => setFavorite((v) => !v)} className={styles["edit"]}>
{isFavorite ? (
<AiFillStar color="#ffc107" />
) : (
<AiOutlineStar color="#ffc107" />
)}
</div>
<LinkTag
href={`/link/edit/${id}`}
className={styles["edit"]}
title="Edit link"
>
<AiFillEdit />
</LinkTag>
<LinkTag
href={`/link/remove/${id}`}
className={styles["remove"]}
title="Remove link"
>
<AiFillDelete color="red" />
</LinkTag>
<FavoriteItem isFavorite={favorite} />
<EditItem type="link" id={id} />
<RemoveItem type="link" id={id} />
</div>
</li>
);

View File

@@ -1,6 +1,9 @@
import LinkTag from "next/link";
import { Category } from "types";
import EditItem from "components/QuickActions/EditItem";
import RemoveItem from "components/QuickActions/RemoveItem";
import LinkItem from "./LinkItem";
import styles from "./links.module.scss";
@@ -15,25 +18,29 @@ export default function Links({ category }: { category: Category }) {
);
}
const { name, links } = category;
const { id, name, links } = category;
if (links.length === 0) {
return (
<div className={styles["no-link"]}>
<p>
Aucun lien pour <b>{category.name}</b>
Aucun lien pour <b>{name}</b>
</p>
<LinkTag href={`/link/create?categoryId=${category.id}`}>
Créer un lien
</LinkTag>
<LinkTag href={`/link/create?categoryId=${id}`}>Créer un lien</LinkTag>
</div>
);
}
return (
<div className={styles["links-wrapper"]}>
<h2>
{name}
<span className={styles["links-count"]}> {links.length}</span>
<h2 className={styles["category-header"]}>
<span>
{name}
<span className={styles["links-count"]}> {links.length}</span>
</span>
<span className={styles["category-controls"]}>
<EditItem type="category" id={id} />
<RemoveItem type="category" id={id} />
</span>
</h2>
<ul className={styles["links"]} key={Math.random()}>
{links.map((link, key) => (

View File

@@ -17,8 +17,6 @@
display: flex;
flex: 1;
flex-direction: column;
overflow-x: hidden;
overflow-y: scroll;
& h2 {
color: $blue;
@@ -33,12 +31,29 @@
}
}
.category-header {
display: flex;
align-items: center;
justify-content: space-between;
& .category-controls {
display: flex;
gap: 0.5em;
align-items: center;
}
}
.links {
height: 100%;
width: 100%;
display: flex;
flex: 1;
gap: 0.5em;
padding: 3px;
flex-direction: column;
animation: fadein 0.3s both; // bug on drag start
overflow-x: hidden;
overflow-y: scroll;
}
.link {
@@ -48,10 +63,9 @@
width: 100%;
color: $blue;
background-color: $white;
padding: 10px 15px;
padding: 0.75em 1em;
border: 1px solid $lightest-grey;
border-radius: 3px;
margin-bottom: 10px;
outline: 3px solid transparent;
display: flex;
align-items: center;

View File

@@ -0,0 +1,27 @@
import LinkTag from "next/link";
import { GrAdd } from "react-icons/gr";
import { Category } from "types";
import styles from "./quickactions.module.scss";
export default function CreateItem({
type,
categoryId,
onClick,
}: {
type: "category" | "link";
categoryId: Category["id"];
onClick?: (event: any) => void; // FIXME: find good event type
}) {
return (
<LinkTag
href={`/${type}/create${categoryId && `?categoryId=${categoryId}`}`}
title={`Create ${type}`}
className={styles["action"]}
onClick={onClick && onClick}
>
<GrAdd />
</LinkTag>
);
}

View File

@@ -0,0 +1,27 @@
import LinkTag from "next/link";
import { AiOutlineEdit } from "react-icons/ai";
import { Category, Link } from "types";
import styles from "./quickactions.module.scss";
export default function EditItem({
type,
id,
onClick,
}: {
type: "category" | "link";
id: Link["id"] | Category["id"];
onClick?: (event: any) => void; // FIXME: find good event type
}) {
return (
<LinkTag
href={`/${type}/edit/${id}`}
title={`Edit ${type}`}
className={styles["action"]}
onClick={onClick && onClick}
>
<AiOutlineEdit />
</LinkTag>
);
}

View File

@@ -0,0 +1,31 @@
import { ReactNode, useState } from "react";
import { AiFillStar, AiOutlineStar } from "react-icons/ai";
export default function FavoriteItem({
isFavorite,
children,
onClick,
}: {
isFavorite: boolean;
children?: ReactNode;
onClick?: (event: any) => void; // FIXME: find good event type
}) {
const starColor = "#ffc107";
const [isItemFavorite, setFavorite] = useState<boolean>(isFavorite);
const handleClick = (event) => {
onClick && onClick(event);
setFavorite((v) => !v);
};
return (
<div onClick={handleClick}>
{isItemFavorite ? (
<AiFillStar color={starColor} />
) : (
<AiOutlineStar color={starColor} />
)}
{children && <>{children}</>}
</div>
);
}

View File

@@ -0,0 +1,27 @@
import LinkTag from "next/link";
import { CgTrashEmpty } from "react-icons/cg";
import { Category, Link } from "types";
import styles from "./quickactions.module.scss";
export default function RemoveItem({
type,
id,
onClick,
}: {
type: "category" | "link";
id: Link["id"] | Category["id"];
onClick?: (event: any) => void; // FIXME: find good event type
}) {
return (
<LinkTag
href={`/${type}/remove/${id}`}
title={`Remove ${type}`}
className={styles["action"]}
onClick={onClick && onClick}
>
<CgTrashEmpty color="red" />
</LinkTag>
);
}

View File

@@ -0,0 +1,18 @@
.action {
border: 0 !important;
margin: 0 !important;
padding: 0 !important;
display: flex;
align-items: center;
justify-content: center;
& svg {
height: 20px;
width: 20px;
transition: 0.15s;
}
&:hover svg {
transform: scale(1.25);
}
}

View File

@@ -1,9 +1,10 @@
import LinkTag from "next/link";
import { useEffect, useRef } from "react";
import { AiFillDelete, AiFillEdit } from "react-icons/ai";
import { Category } from "types";
import EditItem from "components/QuickActions/EditItem";
import RemoveItem from "components/QuickActions/RemoveItem";
import styles from "./categories.module.scss";
interface CategoryItemProps {
@@ -45,20 +46,12 @@ export default function CategoryItem({
function MenuOptions({ id }: { id: number }): JSX.Element {
return (
<div className={styles["menu-item"]}>
<LinkTag
href={`/category/edit/${id}`}
className={styles["option-edit"]}
<EditItem
type="category"
id={id}
onClick={(event) => event.stopPropagation()}
>
<AiFillEdit />
</LinkTag>
<LinkTag
href={`/category/remove/${id}`}
className={styles["option-remove"]}
onClick={(event) => event.stopPropagation()}
>
<AiFillDelete color="red" />
</LinkTag>
/>
<RemoveItem type="category" id={id} />
</div>
);
}