Commit 30ba4def by Madhankumar

pagination in bloglist

parent bf43f185
......@@ -7,6 +7,7 @@
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
text-decoration: none;
--heading1: clamp(1rem, 1.3rem + 2vw, 3rem);
--heading2: clamp(1rem, 1rem + 2vw, 1.7rem);
--heading3: clamp(0.8rem, 0.5rem + 1.5vw, 1.5rem);
......
......@@ -3,21 +3,11 @@ import Button from ".";
export default {
title: "Base/Button",
component: Button,
argTypes: {
backgroundColor: { control: "color" },
},
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
label: "Primary",
primary: true,
};
export const Secondary = Template.bind({});
Secondary.args = {
label: "Secondary",
primary: false,
export const button = {
args: {
variant: "primary",
children: "Button",
},
};
import PropTypes from "prop-types";
import cn from "classnames";
import styles from "./styles.module.css";
const Button = ({ label, primary, classes }) => {
const background = primary ? styles.primary : styles.secondary;
const Button = ({ children, variant, className, ...props }) => {
const classNames = cn({
[styles[variant]]: variant,
[styles[className]]: className,
});
return (
<button className={`${background} ${styles[classes]}`}>{label}</button>
<button className={`${classNames}`} {...props}>
{children}
</button>
);
};
Button.propTypes = {
variant: PropTypes.oneOf(["primary", "secondary", "disabled"]),
};
export default Button;
......@@ -15,16 +15,20 @@ button {
background-color: var(--secondary-bgcolor);
color: var(--secondary-color);
}
button .active {
.disabled {
opacity: 0.7;
background-color: var(--secondary-bgcolor);
color: var(--secondary-color);
}
/* button .active {
background: #5a67d8;
color: #fff;
border: 1px solid #7cbddb;
border-radius: 10px;
font-size: 14px;
font-weight: bold;
}
} */
/*
button.secondary:hover:not(.active) {
color: var(--font-color-900);
}
......@@ -33,10 +37,7 @@ button .disabled {
cursor: not-allowed;
}
/* .next {
font-size: 20px;
} */
button:hover:is(.no-cursor) {
cursor: not-allowed;
user-select: none;
}
} */
......@@ -5,18 +5,23 @@ export default {
title: "Base/Card",
component: Card,
};
export const card = (args) => <Card {...args} />;
card.args = {
export const card = {
args: {
title: "How to get a perfect start for beginning runners",
description:
"Lorem ipsum dolor sit amet consectetur ipsum adipisicing elit. Quis vitae sit.",
image: {
url: require("@img/lifestyle1.jpg"),
url: require("@img/lifestyle1.jpg").default.src,
width: 470,
height: 300,
},
publishedDate: "July 13, 2020.",
authorName: "Isabella Ava",
author: "Isabella Ava",
images: {
url: require("@img/a1.jpg"), // Use require to load images
url: require("@img/a1.jpg").default.src,
width: 80,
height: 80, // Use require to load images
},
readingTime: "1 min",
},
};
import styles from "./styles.module.css";
import PropTypes from "prop-types";
import Image from "next/image";
import Link from "next/link";
import Icons from "../icons";
import PropTypes from "prop-types";
import Icons from "@components/base/icons";
import styles from "./styles.module.css";
const Card = ({
title,
description,
image,
publishedDate,
authorName,
author,
images,
readingTime,
}) => {
return (
<div className={styles.card}>
<Link href="#">
<Image className={styles.img} src={image.url} alt={title} />
<Image
className={styles.img}
src={image.url}
height={image.height}
width={image.width}
alt={title}
/>
<p className={styles.title}>{title}</p>
</Link>
<div className={styles["card-content"]}>
<Link href="#" className={styles.title}>
<p>{title}</p>
</Link>
<p className={styles.description}>{description}</p>
<div className={styles.authorcontainer}>
<p className={styles.description}>{description}</p>
<div className={styles.cardbottom}>
<Image className={styles.img} src={images.url} alt={authorName} />
<Image
className={styles.img}
src={images.url}
height={images.height}
width={images.width}
alt={author}
/>
<div className={styles.authordescription}>
<p>{authorName}</p>
<p className={styles.authorName}>{author}</p>
<div className={styles["author-desc"]}>
{publishedDate}
<span className={styles.icon}>
......@@ -39,7 +48,6 @@ const Card = ({
</div>
</div>
</div>
</div>
);
};
Card.propTypes = {
......@@ -49,7 +57,7 @@ Card.propTypes = {
url: PropTypes.string,
}),
publishedDate: PropTypes.string,
authorName: PropTypes.string,
author: PropTypes.string,
images: PropTypes.shape({
url: PropTypes.string, // Use PropTypes.string for images
}),
......
.img {
max-width: 100%;
height: auto;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
}
.card {
background-color: var(--card-bg);
border-radius: 20px;
......@@ -13,66 +5,73 @@
flex-direction: column;
transition: all 0.3s ease-in-out;
word-wrap: break-word;
}
.card:hover {
&:hover {
transform: translateY(-10px);
}
}
.img {
max-width: 100%;
height: auto;
.card-content {
padding: 1.5rem;
padding-bottom: 1rem;
}
.authordescription > p {
font-size: 18px;
font-weight: 500;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
}
}
.cardbottom {
.authorcontainer {
padding: 1.5rem;
padding-top: 0rem;
margin-top: -20px;
& .description {
color: var(--font-color-300);
line-height: 1.5em;
font-weight: 600px;
word-wrap: break-word;
}
.cardbottom {
display: grid;
grid-template-columns: 0.5fr 2fr;
line-height: 0;
align-items: center;
grid-gap: 16px;
color: var(--font-color-900);
}
.cardbottom img {
.img {
border-radius: 50%;
height: auto;
max-width: 100%;
}
.description {
}
.authordescription {
.authorName {
font-size: 18px;
font-weight: 500;
}
.author-desc {
display: flex;
align-items: center;
gap: 1rem;
color: var(--font-color-300);
line-height: 1.5em;
font-weight: 600px;
word-wrap: break-word;
line-height: 0.5em;
& span {
display: flex;
align-items: center;
}
}
}
}
}
.title {
color: var(--font-color-900);
font-size: 22px;
text-decoration: none;
line-height: 1.5em;
font-weight: 600;
}
.title:hover {
padding: 1.5rem;
padding-bottom: 0rem;
&:hover {
color: #5a67d8;
}
.author-desc {
display: flex;
align-items: center;
gap: 1rem;
color: var(--font-color-300);
line-height: 0.5em;
}
.author-desc span {
display: flex;
align-items: center;
}
}
@media screen and (min-width: 802px) {
@media screen and (min-width: 768px) {
.card {
width: min(90%, 25rem);
}
......
import styles from "./styles.module.css";
import Search from "../search";
import Icons from "../icons";
import { useTheme } from "@/app/context/index";
import Link from "next/link";
import Search from "@components/base/search";
import Icons from "@components/base/icons";
import { useTheme } from "@context/index";
import styles from "./styles.module.css";
function Header({ name, onThemeChange, onSearch, onClose }) {
const { theme, toggleTheme } = useTheme();
......@@ -32,9 +32,6 @@ function Header({ name, onThemeChange, onSearch, onClose }) {
<div onClick={handleTheme} className={styles.themelight}>
<Icons name={theme == "light" ? "moon" : "sun"} size="medium" />
<span className={styles.mobilemenu}>
<Icons name="hamburger" size="medium" classes="menu-icon" />
</span>
</div>
</nav>
</div>
......
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.7em 10%;
}
.container {
background-color: var(--card-bg);
width: 100%;
}
.header {
position: sticky;
top: 57px;
height: 179px;
}
.navbar-brand {
.container {
background-color: var(--card-bg);
width: 100%;
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.7em 10%;
.navbar-brand {
display: grid;
grid-template-columns: auto 1fr;
gap: 1rem;
align-items: center;
text-decoration: none;
}
.navbar-brand h2 {
h2 {
color: var(--title-color);
}
.mobilemenu {
display: block;
}
.themelight {
}
.themelight {
display: flex;
gap: 1rem;
}
.search {
}
.search {
display: none;
}
}
}
}
}
@media screen and (min-width: 991px) {
.mobilemenu {
display: none;
}
.search {
display: block;
}
......
......@@ -3,7 +3,6 @@ import Icons from ".";
export default {
title: "Base/Icons",
component: Icons,
argTypes: {},
};
const iconList = [
"close",
......
import styles from "./styles.module.css";
import PropTypes from "prop-types";
import cn from "classnames";
import styles from "./styles.module.css";
const Icons = ({ name, size, classes }) => {
const icons = {
search: (
......@@ -92,10 +94,11 @@ const Icons = ({ name, size, classes }) => {
</svg>
),
};
return (
<span className={`${styles[classes]} ${styles[size]}`}>{icons[name]}</span>
);
const classNames = cn({
[styles[classes]]: classes,
[styles[size]]: size,
});
return <span className={classNames}>{icons[name]}</span>;
};
Icons.propTypes = {
......
import styles from "./styles.module.css";
import Icons from "../icons";
import { useState, useEffect } from "react";
import Icons from "@components/base/icons";
import styles from "./styles.module.css";
const Search = ({ onSearch, onClose }) => {
const [text, setText] = useState("");
......@@ -26,12 +26,12 @@ const Search = ({ onSearch, onClose }) => {
};
return (
<div className={styles["search-input"]}>
<div className={styles["search"]}>
<span className={`${styles["search-icon"]}`}>
<Icons name="search" size="small" />
</span>
<input
className={styles.search}
className={styles["search-input"]}
type="text"
autoFocus={true}
value={text}
......@@ -40,7 +40,7 @@ const Search = ({ onSearch, onClose }) => {
/>
{text && (
<span className={`${styles["close-icon"]}`} onClick={handleCustomClear}>
<Icons name="close" />
<Icons name="close" size="small" />
</span>
)}
</div>
......
.search {
.search{
position: relative;
display: inline-block;
border-radius: 2px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;
.search-input {
height: 48px;
width: 30vw;
background: #f4f4f4;
......@@ -7,12 +13,6 @@
padding-left: 3rem;
font-size: 16px;
}
.search-input {
position: relative;
display: inline-block;
border-radius: 2px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;
}
.search-icon {
position: absolute;
top: 14px;
......@@ -28,3 +28,5 @@
top: 15px;
right: 15px;
}
}
const Typography = () => {
return (
<div>
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer congue
placerat lobortis. Pellentesque facilisis nisl orci, non accumsan massa
auctor quis. Proin blandit sollicitudin turpis id laoreet. Vivamus
tincidunt maximus sem sit amet pulvinar. Praesent faucibus et tellus
quis hendrerit. Vestibulum a dui et sem egestas luctus.
</p>
</div>
);
};
export default Typography;
import Typography from ".";
export default {
title: "Base/Typography",
component: Typography,
};
export const typography = {};
export const Typography = () => (
<div>
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer congue
placerat lobortis. Pellentesque facilisis nisl orci, non accumsan massa
auctor quis. Proin blandit sollicitudin turpis id laoreet. Vivamus
tincidunt maximus sem sit amet pulvinar. Praesent faucibus et tellus quis
hendrerit. Vestibulum a dui et sem egestas luctus.
</p>
</div>
);
......@@ -3,9 +3,8 @@ export default {
title: "Top-Level/Blog-Lists",
component: BlogLists,
};
export const blogLists = (args) => <BlogLists {...args} />;
blogLists.args = {
export const blogLists = {
args: {
title: "Lifestyle",
description:
"Lorem ipsum dolor sit amet elit. Id quaerat amet ipsum sunt et quos dolorum",
......@@ -18,7 +17,7 @@ blogLists.args = {
url: require("@img/lifestyle1.jpg"),
},
publishedDate: "July 13, 2020.",
authorName: "Isabella ava",
author: "Isabella ava",
images: {
url: require("@img/a1.jpg"),
},
......@@ -34,7 +33,7 @@ blogLists.args = {
},
publishedDate: "July 13, 2020.",
authorName: "Charlotte mia",
author: "Charlotte mia",
images: {
url: require("@img/a2.jpg"),
},
......@@ -49,7 +48,7 @@ blogLists.args = {
url: require("@img/lifestyle3.jpg"),
},
publishedDate: "July 13, 2020.",
authorName: "Elizabeth",
author: "Elizabeth",
images: {
url: require("@img/a3.jpg"),
},
......@@ -64,7 +63,7 @@ blogLists.args = {
url: require("@img/lifestyle4.jpg"),
},
publishedDate: "July 13, 2020.",
authorName: "Charlotte mia",
author: "Charlotte mia",
images: {
url: require("@img/a1.jpg"),
},
......@@ -78,7 +77,7 @@ blogLists.args = {
url: require("@img/lifestyle5.jpg"),
},
publishedDate: "July 13, 2020.",
authorName: "Elizabeth",
author: "Elizabeth",
images: {
url: require("@img/a3.jpg"),
},
......@@ -93,11 +92,54 @@ blogLists.args = {
url: require("@img/lifestyle6.jpg"),
},
publishedDate: "July 13, 2020.",
authorName: "Isabella ava",
author: "Isabella ava",
images: {
url: require("@img/a1.jpg"),
},
readingTime: "1min",
},
{
title: "3 New outfit Formulas To Add to your Capsule Wardrobe",
description:
"Lorem ipsum dolor sit amet consectetur ipsum adipisicing elit. Quis vitae sit.",
image: {
url: require("@img/lifestyle6.jpg"),
},
publishedDate: "July 13, 2020.",
author: "Isabella ava",
images: {
url: require("@img/a1.jpg"),
},
readingTime: "1min",
},
{
title: "3 New outfit Formulas To Add to your Capsule Wardrobe",
description:
"Lorem ipsum dolor sit amet consectetur ipsum adipisicing elit. Quis vitae sit.",
image: {
url: require("@img/lifestyle6.jpg"),
},
publishedDate: "July 13, 2020.",
author: "Isabella ava",
images: {
url: require("@img/a1.jpg"),
},
readingTime: "1min",
},
{
title: "3 New outfit Formulas To Add to your Capsule Wardrobe",
description:
"Lorem ipsum dolor sit amet consectetur ipsum adipisicing elit. Quis vitae sit.",
image: {
url: require("@img/lifestyle6.jpg"),
},
publishedDate: "July 13, 2020.",
author: "Isabella ava",
images: {
url: require("@img/a1.jpg"),
},
readingTime: "1min",
},
],
},
};
import React, { useState } from "react";
import PropTypes from "prop-types";
import Card from "@/components/base/card";
import Pagination from "@components/top-level/pagination";
import styles from "./styles.module.css";
const BlogLists = ({ title, description, blogs }) => {
const length = blogs.length;
const itemsPerPage = 6;
const [currentPage, setCurrentPage] = useState(1);
// Calculate the start and end indices for the current page
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const slicedData = blogs.slice(startIndex, endIndex);
// Handle page change
const handlePageChange = (pageNumber) => {
setCurrentPage(pageNumber);
};
return (
<div className={styles["blog-container"]}>
<h1 className={styles.title}>{title}</h1>
<p className={styles.description}>{description}</p>
<div className={styles.row}>
{blogs.map((blogData, i) => (
<div key={i} className={styles["card-container"]}>
{slicedData.map((blogData, i) => (
<div key={i} className={styles.col}>
<Card {...blogData} />
</div>
))}
</div>
<div className={styles.pagination}>
<Pagination
currentPage={currentPage}
total={length}
perPage={itemsPerPage}
onPageChange={handlePageChange}
/>
</div>
</div>
);
};
BlogLists.propTypes = {
title: PropTypes.string,
description: PropTypes.string,
......
.blog-container {
max-width: 1200px;
margin: 0 auto;
}
.row {
display: grid;
grid-row-gap: 3rem;
}
.card-container {
display: flex;
align-self: normal;
flex: 1 0 auto;
}
.title {
.title {
font-size: 38px;
line-height: 25px;
font-weight: 600;
......@@ -25,18 +13,36 @@
padding-inline: 1.5rem;
margin-bottom: 3em;
}
@media screen and (min-width: 802px) {
.row {
display: grid;
grid-row-gap: 3rem;
.col {
display: flex;
align-self: normal;
flex: 1 0 auto;
}
}
}
.pagination{
margin-top: 3rem;
}
@media screen and (min-width: 768px) {
.row {
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
justify-items: center;
}
}
@media screen and (min-width: 1440px) {
.bloglist-container {
padding: 0 100px;
.row {
grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr));
justify-items: center;
}
.bloglist-container {
padding: 0 100px;
}
}
import { useState, useEffect } from "react";
import styles from "./styles.module.css";
import PropTypes from "prop-types";
import Button from "@/components/base/button";
import styles from "./styles.module.css";
function Pagination({ total, currentPage, onPageChange }) {
function Pagination({ total, currentPage, onPageChange, perPage }) {
//Set number of pages
const numberOfPages = [];
const totalPage = total <= 1 ? 1 : total;
const totalPages = Math.round(total / perPage);
const totalPage = totalPages <= 1 ? 1 : totalPages;
for (let i = 1; i <= totalPage; i++) {
numberOfPages.push(i);
}
......@@ -18,7 +20,7 @@ function Pagination({ total, currentPage, onPageChange }) {
const [arrOfCurrButtons, setArrOfCurrButtons] = useState([]);
useEffect(() => {
let tempNumberOfPages = [...arrOfCurrButtons];
//adding dots
let dotsInitial = "...";
let dotsLeft = "...";
let dotsRight = "...";
......@@ -49,7 +51,7 @@ function Pagination({ total, currentPage, onPageChange }) {
}
setArrOfCurrButtons(tempNumberOfPages);
}, [total, currentButton]);
}, [total, currentButton, perPage]);
//update currentButton value if currentPageNo changes
useEffect(() => {
......@@ -64,43 +66,42 @@ function Pagination({ total, currentPage, onPageChange }) {
return (
<div className={styles["pagination-container"]}>
<span className={styles.previous}>
<Button
variant={currentButton <= 1 ? "disabled" : "secondary"}
onClick={() =>
currentButton <= 1 ? "" : handleCurrentPage(currentButton - 1)
}
>
&laquo; Prev
</Button>
</span>
{arrOfCurrButtons.map((item, index) => {
return (
<span
key={index}
onClick={() => (item === "..." ? "" : handleCurrentPage(item))}
>
<span key={index}>
<Button
label={item}
variant={currentButton === item ? "primary" : "secondary"}
primary={currentButton === item ? true : false}
classes={`${
item === "..."
? "no-cursor"
: currentButton === item
? "active"
: ""
}`}
/>
onClick={() => (item === "..." ? "" : handleCurrentPage(item))}
>
{item}
</Button>
</span>
);
})}
<span
<span className={styles.next}>
<Button
variant={
currentButton === numberOfPages.length ? "disabled" : "secondary"
}
onClick={() =>
currentButton === "..." || currentButton === numberOfPages.length
currentButton === numberOfPages.length
? ""
: handleCurrentPage(currentButton + 1)
}
>
<Button
label="Next »"
className={`${
currentButton === "..."
? "no-cursor"
: currentButton === numberOfPages.length
? "disabled"
: ""
}`}
/>
Next &raquo;
</Button>
</span>
</div>
);
......
......@@ -11,5 +11,6 @@ export const pagination = {
args: {
total: 10,
currentPage: 1,
perPage: 2,
},
};
......@@ -6,9 +6,7 @@
width: 100%;
font-weight: 500;
font-size: 15px;
}
.pagination-container span {
> span {
display: flex;
justify-content: center;
align-items: center;
......@@ -19,4 +17,14 @@
text-decoration: none;
transition: background-color 0.2s;
cursor: pointer;
}
}
/* .previous button:active,
.next button:active {
background-color: var(--primary-bgcolor);
color: var(--primary-color);
} */
:is(.previous, .next) button:active {
background-color: var(--primary-bgcolor);
color: var(--primary-color);
}
import PropTypes from "prop-types";
import Image from "next/image";
import styles from "./styles.module.css";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import PropTypes from "prop-types";
import styles from "./styles.module.css";
function SingleBlog({
title,
publishedDate,
authorName,
author,
category,
readingTime,
images,
image,
categories,
markdown,
}) {
......@@ -29,7 +28,7 @@ function SingleBlog({
<li>
By&nbsp;
<a href="#" className={styles["list-bold"]}>
{authorName}
{author}
</a>
</li>
<li>
......@@ -48,7 +47,13 @@ function SingleBlog({
</div>
<div className={styles["blog-container"]}>
<div className={styles.blogimage}>
<Image className={styles.img} src={images.url} alt={title} />
<Image
className={styles.img}
src={image.url}
alt={title}
width={image.width}
height={image.height}
/>
</div>
<div className={styles["blog-content"]}>
<ReactMarkdown remarkPlugins={[remarkGfm]}>{markdown}</ReactMarkdown>
......@@ -73,6 +78,8 @@ SingleBlog.propTypes = {
categories: PropTypes.array,
image: PropTypes.shape({
url: PropTypes.string,
width: PropTypes.number,
height: PropTypes.number,
}),
};
export default SingleBlog;
......@@ -2,16 +2,16 @@ import SingleBlog from ".";
export default {
title: "Top-Level/Single-Blog",
component: SingleBlog,
argTypes: {},
};
export const singleBlog = (args) => <SingleBlog {...args} />;
singleBlog.args = {
export const singleBlog = {
args: {
title: "Create an Art that shows the beauty in everyone ideas of flaws.",
publishedDate: "July 11,2020",
authorName: "Charlotte mia",
images: {
url: require("@/public/images/blogsingle.jpg"),
author: "Charlotte mia",
image: {
url: require("@/public/images/blogsingle.jpg").default.src,
width: 1100,
height: 400,
},
category: "Fashion",
......@@ -54,4 +54,5 @@ Lorem faucibus fusce ante vitae justo efficitur elementum.Donec ipsum faucibus a
vitae justo efficitur elementum.Donec et ipsum faucibus.Donec et ipsum faucibus arcu.
Fusce faucibus arcu faucibus ante vitae justo efficitur elementum.Donec ipsum faucibus.Donec ipsum faucibus arcu.`,
},
};
......@@ -3,6 +3,7 @@
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@components/*": ["components/*"],
"@img/*": ["public/images/*"],
"@context/*": ["app/context/*"],
}
......
......@@ -11,9 +11,11 @@
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"classnames": "^2.3.2",
"gray-matter": "^4.0.3",
"next": "14.0.2",
"next-themes": "^0.2.1",
"prettier": "^3.1.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^4.12.0",
......@@ -4396,6 +4398,21 @@
"node": ">= 6"
}
},
"node_modules/@storybook/cli/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/@storybook/client-logger": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.5.3.tgz",
......@@ -4434,6 +4451,21 @@
"url": "https://opencollective.com/storybook"
}
},
"node_modules/@storybook/codemod/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/@storybook/components": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.5.3.tgz",
......@@ -7637,6 +7669,11 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
......@@ -14437,15 +14474,14 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz",
"integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==",
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
......
......@@ -14,9 +14,11 @@
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"classnames": "^2.3.2",
"gray-matter": "^4.0.3",
"next": "14.0.2",
"next-themes": "^0.2.1",
"prettier": "^3.1.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^4.12.0",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment