feat: add theme switcher and refactor conference components to use new Room interface
This commit is contained in:
parent
bc8216fbe2
commit
b4d054de36
@ -3,9 +3,9 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbopack",
|
"dev": "next dev --turbopack -p 4000",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start -p 4000",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -20,6 +20,7 @@
|
|||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"next": "15.0.3",
|
"next": "15.0.3",
|
||||||
"next-auth": "^4.24.10",
|
"next-auth": "^4.24.10",
|
||||||
|
"next-themes": "^0.4.4",
|
||||||
"react": "19.0.0-rc-66855b96-20241106",
|
"react": "19.0.0-rc-66855b96-20241106",
|
||||||
"react-dom": "19.0.0-rc-66855b96-20241106",
|
"react-dom": "19.0.0-rc-66855b96-20241106",
|
||||||
"zustand": "^5.0.2"
|
"zustand": "^5.0.2"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { NextUIProvider } from "@nextui-org/react";
|
import { NextUIProvider } from "@nextui-org/react";
|
||||||
import { SessionProvider } from "next-auth/react";
|
import { SessionProvider } from "next-auth/react";
|
||||||
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
|
|
||||||
export default function AppWrapper({
|
export default function AppWrapper({
|
||||||
children,
|
children,
|
||||||
@ -10,7 +11,11 @@ export default function AppWrapper({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<SessionProvider>
|
<SessionProvider>
|
||||||
<NextUIProvider>{children}</NextUIProvider>
|
<NextUIProvider>
|
||||||
|
<NextThemesProvider attribute="class" defaultTheme="dark">
|
||||||
|
{children}
|
||||||
|
</NextThemesProvider>
|
||||||
|
</NextUIProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { parseDate, Time } from "@internationalized/date";
|
import { parseDate, Time } from "@internationalized/date";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Button,
|
||||||
Card,
|
Card,
|
||||||
CardBody,
|
CardBody,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
@ -10,49 +11,64 @@ import {
|
|||||||
Divider,
|
Divider,
|
||||||
TimeInput,
|
TimeInput,
|
||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
import { Conference } from "./Conference";
|
import { Room } from "./Conference";
|
||||||
|
import moment from "moment";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
export const ConferenceCard = ({
|
export const ConferenceCard = ({
|
||||||
id,
|
id,
|
||||||
title,
|
name,
|
||||||
author,
|
|
||||||
date,
|
date,
|
||||||
hours,
|
Times,
|
||||||
}: Conference) => {
|
Presentator
|
||||||
|
}: Room) => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="max-w-[400px]">
|
<Card className="max-w-[600px]">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-md">{title}</p>
|
<p className="text-md">{name}</p>
|
||||||
<p className="text-small text-default-500">{author}</p>
|
<p className="text-small text-default-500">{Presentator.username}</p>
|
||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<Divider />
|
<Divider />
|
||||||
<CardBody className="gap-2">
|
<CardBody>
|
||||||
<DateInput isReadOnly label="Date" value={parseDate(date)} />
|
{Times.map((time) => (
|
||||||
{hours.map((hour, hourIndex) => (
|
<div className="flex flex-col gap-2" key={`${time.id}`}>
|
||||||
<div
|
<DateInput isReadOnly label="Date" value={parseDate(moment(date).format("YYYY-MM-DD"))} />
|
||||||
className="flex items-center gap-2"
|
<div className="flex items-center gap-2">
|
||||||
key={`${id}-${hourIndex}`}
|
<TimeInput
|
||||||
>
|
isReadOnly
|
||||||
<TimeInput
|
label="Start"
|
||||||
isReadOnly
|
hourCycle={24}
|
||||||
label="Start"
|
value={
|
||||||
hourCycle={24}
|
new Time(moment(time.startTime).hours(), moment(time.startTime).minutes())
|
||||||
value={
|
}
|
||||||
new Time(hour.start.hours, hour.start.minutes)
|
/>
|
||||||
}
|
<span>-</span>
|
||||||
/>
|
<TimeInput
|
||||||
<span>-</span>
|
isReadOnly
|
||||||
<TimeInput
|
label="End"
|
||||||
isReadOnly
|
hourCycle={24}
|
||||||
label="End"
|
value={new Time(moment(time.endTime).hours(), moment(time.endTime).minutes())}
|
||||||
hourCycle={24}
|
/>
|
||||||
value={new Time(hour.end.hours, hour.end.minutes)}
|
</div>
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
<div className="flex p-2">
|
||||||
|
<Button
|
||||||
|
className={"bg-transparent text-foreground border-default-200"}
|
||||||
|
color="primary"
|
||||||
|
radius="full"
|
||||||
|
size="sm"
|
||||||
|
variant={"bordered"}
|
||||||
|
onPress={() => {
|
||||||
|
router.push(`/room/${id}`);
|
||||||
|
}}
|
||||||
|
>Join</Button>
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
27
src/app/components/Conference/Conference.d.ts
vendored
27
src/app/components/Conference/Conference.d.ts
vendored
@ -1,16 +1,17 @@
|
|||||||
export interface Conference {
|
export interface Room {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
name: string;
|
||||||
author: string;
|
|
||||||
date: string;
|
date: string;
|
||||||
hours: {
|
Times: {
|
||||||
start: {
|
id: number;
|
||||||
hours: number;
|
startTime: string;
|
||||||
minutes: number;
|
endTime: string;
|
||||||
};
|
roomId: string;
|
||||||
end: {
|
|
||||||
hours: number;
|
|
||||||
minutes: number;
|
|
||||||
};
|
|
||||||
}[];
|
}[];
|
||||||
}
|
Presentator: {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
role: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,22 @@
|
|||||||
|
"use client"
|
||||||
import { ConferenceCard } from "./Card";
|
import { ConferenceCard } from "./Card";
|
||||||
import { Conference } from "./Conference";
|
import { Room } from "./Conference";
|
||||||
|
|
||||||
export const ConferenceList = ({
|
export const ConferenceList = ({
|
||||||
conferences,
|
rooms,
|
||||||
}: {
|
}: {
|
||||||
conferences: Conference[];
|
rooms: Room[];
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{conferences.map((conference) => (
|
{rooms.map((room) => (
|
||||||
<ConferenceCard
|
<ConferenceCard
|
||||||
key={conference.id}
|
key={room.id}
|
||||||
id={conference.id}
|
id={room.id}
|
||||||
title={conference.title}
|
name={room.name}
|
||||||
author={conference.author}
|
date={room.date}
|
||||||
date={conference.date}
|
Presentator={room.Presentator}
|
||||||
hours={conference.hours}
|
Times={room.Times}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
NavbarContent,
|
NavbarContent,
|
||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
|
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher";
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
@ -18,6 +19,7 @@ export const Header = () => {
|
|||||||
<Navbar className="mb-2">
|
<Navbar className="mb-2">
|
||||||
<NavbarBrand>
|
<NavbarBrand>
|
||||||
<p className="font-bold text-inherit">Toogether</p>
|
<p className="font-bold text-inherit">Toogether</p>
|
||||||
|
<ThemeSwitcher />
|
||||||
</NavbarBrand>
|
</NavbarBrand>
|
||||||
<NavbarContent as="div" justify="end">
|
<NavbarContent as="div" justify="end">
|
||||||
<Dropdown placement="bottom-end">
|
<Dropdown placement="bottom-end">
|
||||||
|
23
src/app/components/ThemeSwitcher/ThemeSwitcher.tsx
Normal file
23
src/app/components/ThemeSwitcher/ThemeSwitcher.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
"use client";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export const ThemeSwitcher = () => {
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
const { theme, setTheme } = useTheme();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!mounted) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`fixed bottom-4 right-4 rounded-lg ${theme === "light" ? "bg-black" : "bg-white"} p-2`}>
|
||||||
|
{theme === "light" ? (
|
||||||
|
<button onClick={() => setTheme("dark")}>🌙</button>) : (
|
||||||
|
<button onClick={() => setTheme("light")}>☀️</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -7,7 +7,7 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="fr">
|
<html lang="fr" suppressHydrationWarning>
|
||||||
<body>
|
<body>
|
||||||
<AppWrapper>{children}</AppWrapper>
|
<AppWrapper>{children}</AppWrapper>
|
||||||
</body>
|
</body>
|
||||||
|
145
src/app/page.tsx
145
src/app/page.tsx
@ -1,54 +1,115 @@
|
|||||||
|
"use client";
|
||||||
|
import { Card, Divider, Skeleton } from "@nextui-org/react";
|
||||||
|
import moment from "moment";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Room } from "./components/Conference/Conference";
|
||||||
import { ConferenceList } from "./components/Conference/List";
|
import { ConferenceList } from "./components/Conference/List";
|
||||||
import { Header } from "./components/Header";
|
import { Header } from "./components/Header";
|
||||||
|
import { axiosInstance } from "./lib/axios";
|
||||||
|
|
||||||
const RandomConferenceData = [
|
const SkeletonCard = () => {
|
||||||
{
|
return <Card className="w-[200px] space-y-5 p-4" radius="lg">
|
||||||
id: "1",
|
<div className="flex flex-col gap-2">
|
||||||
title: "Conference sur les conférences",
|
<Skeleton className="w-4/5 rounded-lg">
|
||||||
author: "Rémi Formentel",
|
<div className="h-3 w-4/5 rounded-lg bg-default-200" />
|
||||||
date: "2021-09-01",
|
</Skeleton>
|
||||||
hours: [
|
<Skeleton className="w-2/5 rounded-lg">
|
||||||
{
|
<div className="h-3 w-2/5 rounded-lg bg-default-300" />
|
||||||
start: { hours: 9, minutes: 0 },
|
</Skeleton>
|
||||||
end: { hours: 12, minutes: 0 },
|
</div>
|
||||||
},
|
<Divider />
|
||||||
{
|
<Skeleton className="rounded-lg">
|
||||||
start: { hours: 13, minutes: 0 },
|
<div className="h-12 rounded-lg bg-default-300" />
|
||||||
end: { hours: 15, minutes: 0 },
|
</Skeleton>
|
||||||
},
|
<div className="flex items-center gap-2">
|
||||||
],
|
<Skeleton className="rounded-lg w-1/2">
|
||||||
},
|
<div className="h-10 rounded-lg bg-default-300" />
|
||||||
{
|
</Skeleton>
|
||||||
id: "2",
|
<span>-</span>
|
||||||
title: "Apprendre a dev pour les nuls",
|
<Skeleton className="rounded-lg w-1/2">
|
||||||
author: "Fabien Taupin",
|
<div className="h-10 rounded-lg bg-default-300" />
|
||||||
date: "2021-09-01",
|
</Skeleton>
|
||||||
hours: [
|
</div>
|
||||||
{
|
</Card>
|
||||||
start: { hours: 18, minutes: 0 },
|
}
|
||||||
end: { hours: 23, minutes: 0 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
|
const [roomsLoading, setRoomsLoading] = useState(true);
|
||||||
|
const [rooms, setRooms] = useState<{
|
||||||
|
future: Room[];
|
||||||
|
actual: Room[];
|
||||||
|
past: Room[];
|
||||||
|
}>({
|
||||||
|
future: [],
|
||||||
|
actual: [],
|
||||||
|
past: []
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axiosInstance.get<{ id: string, name: string, createdAt: string }[]>("/@me/class")
|
||||||
|
.then((classResponse) => {
|
||||||
|
classResponse.data.length > 0 &&
|
||||||
|
axiosInstance.get<Room[]>(`/@me/class/${classResponse.data[0].id}/rooms`)
|
||||||
|
.then(classes => {
|
||||||
|
// Filter rooms by date, get future, actual and past rooms
|
||||||
|
const future = classes.data.filter(room => moment(room.date).isAfter(moment(), "day"));
|
||||||
|
const actual = classes.data.filter(room => moment(room.date).isSame(moment(), "day"));
|
||||||
|
const past = classes.data.filter(room => moment(room.date).isBefore(moment()));
|
||||||
|
|
||||||
|
setRooms({ future, actual, past });
|
||||||
|
setRoomsLoading(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
<main className="flex flex-col gap-8 p-4">
|
<main className="flex flex-col gap-8 p-4">
|
||||||
<section className="flex flex-col gap-2">
|
{roomsLoading
|
||||||
<h2 className="font-semibold text-lg">Cours a venir</h2>
|
? <>
|
||||||
<ConferenceList conferences={RandomConferenceData} />
|
<section className="flex flex-col gap-2">
|
||||||
</section>
|
<h2 className="font-semibold text-lg">Cours a venir</h2>
|
||||||
<section className="flex flex-col gap-2">
|
<div className="flex gap-4">
|
||||||
<h2 className="font-semibold text-lg">Cours passés</h2>
|
<SkeletonCard />
|
||||||
<ConferenceList conferences={RandomConferenceData} />
|
<SkeletonCard />
|
||||||
</section>
|
<SkeletonCard />
|
||||||
<section className="flex flex-col gap-2">
|
</div>
|
||||||
<h2 className="font-semibold text-lg">Autres cours</h2>
|
</section>
|
||||||
<ConferenceList conferences={RandomConferenceData} />
|
<section className="flex flex-col gap-2">
|
||||||
</section>
|
<h2 className="font-semibold text-lg">Cours actuels</h2>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<SkeletonCard />
|
||||||
|
<SkeletonCard />
|
||||||
|
<SkeletonCard />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="flex flex-col gap-2">
|
||||||
|
<h2 className="font-semibold text-lg">Cours passés</h2>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<SkeletonCard />
|
||||||
|
<SkeletonCard />
|
||||||
|
<SkeletonCard />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
: <>
|
||||||
|
<section className="flex flex-col gap-2">
|
||||||
|
<h2 className="font-semibold text-lg">Cours a venir</h2>
|
||||||
|
<ConferenceList rooms={rooms.future} />
|
||||||
|
</section>
|
||||||
|
<section className="flex flex-col gap-2">
|
||||||
|
<h2 className="font-semibold text-lg">Cours actuels</h2>
|
||||||
|
<ConferenceList rooms={rooms.actual} />
|
||||||
|
</section>
|
||||||
|
<section className="flex flex-col gap-2">
|
||||||
|
<h2 className="font-semibold text-lg">Cours passés</h2>
|
||||||
|
<ConferenceList rooms={rooms.past} />
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
|
||||||
|
}
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -14,16 +14,6 @@ export default {
|
|||||||
background: "var(--background)",
|
background: "var(--background)",
|
||||||
foreground: "var(--foreground)",
|
foreground: "var(--foreground)",
|
||||||
},
|
},
|
||||||
animation: {
|
|
||||||
"gradient-x": "gradient-x 5s ease infinite",
|
|
||||||
},
|
|
||||||
keyframes: {
|
|
||||||
"gradient-x": {
|
|
||||||
"0%": { "background-position": "0% 50%" },
|
|
||||||
"50%": { "background-position": "100% 50%" },
|
|
||||||
"100%": { "background-position": "0% 50%" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
darkMode: "class",
|
darkMode: "class",
|
||||||
|
26
yarn.lock
26
yarn.lock
@ -4148,6 +4148,11 @@ next-auth@^4.24.10:
|
|||||||
preact-render-to-string "^5.1.19"
|
preact-render-to-string "^5.1.19"
|
||||||
uuid "^8.3.2"
|
uuid "^8.3.2"
|
||||||
|
|
||||||
|
next-themes@^0.4.4:
|
||||||
|
version "0.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.4.tgz#ce6f68a4af543821bbc4755b59c0d3ced55c2d13"
|
||||||
|
integrity sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==
|
||||||
|
|
||||||
next@15.0.3:
|
next@15.0.3:
|
||||||
version "15.0.3"
|
version "15.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/next/-/next-15.0.3.tgz#804f5b772e7570ef1f088542a59860914d3288e9"
|
resolved "https://registry.yarnpkg.com/next/-/next-15.0.3.tgz#804f5b772e7570ef1f088542a59860914d3288e9"
|
||||||
@ -4730,8 +4735,16 @@ streamsearch@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
||||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
|
"string-width-cjs@npm:string-width@^4.2.0":
|
||||||
name string-width-cjs
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
string-width@^4.1.0:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
@ -4812,7 +4825,14 @@ string.prototype.trimstart@^1.0.8:
|
|||||||
define-properties "^1.2.1"
|
define-properties "^1.2.1"
|
||||||
es-object-atoms "^1.0.0"
|
es-object-atoms "^1.0.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
Loading…
Reference in New Issue
Block a user