misc: updates & shit
This commit is contained in:
parent
e22c7dafa1
commit
ad66016115
20 changed files with 2087 additions and 1303 deletions
|
@ -1,4 +1,4 @@
|
||||||
import UserAuthForm from '@/ui/UserAuthForm';
|
import UserAuthForm from '@/components/ui/UserAuthForm';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import UserAuthForm from '@/ui/UserAuthForm';
|
import UserAuthForm from '@/components/ui/UserAuthForm';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useContext } from 'react';
|
||||||
|
|
||||||
import { UserContext } from '@/context/user';
|
import { UserContext } from '@/context/user';
|
||||||
|
|
||||||
import Badge from '@/ui/Badge';
|
import Badge from '@/components/ui/Badge';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const { data: me } = useContext(UserContext);
|
const { data: me } = useContext(UserContext);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { type ReactNode } from 'react';
|
import { type ReactNode } from 'react';
|
||||||
|
|
||||||
import { UserProvider } from '@/context/user';
|
import { UserProvider } from '@/context/user';
|
||||||
import Wrapper from '@/ui/dashboard/Wrapper';
|
import Wrapper from '@/components/ui/dashboard/Wrapper';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
export default async function Layout({ children }: { children: ReactNode }) {
|
export default async function Layout({ children }: { children: ReactNode }) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Leaderboard from '@/ui/Leaderboard';
|
import Leaderboard from '@/components/ui/Leaderboard';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
|
import Card from '@/components/ui/Card';
|
||||||
import { UserContext } from '@/context/user';
|
import { UserContext } from '@/context/user';
|
||||||
import Card from '@/ui/Card';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const { data: me, isLoading } = useContext(UserContext);
|
const { data: me, isLoading } = useContext(UserContext);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getPuzzle } from '@/lib/puzzles';
|
import { getPuzzle } from '@/lib/puzzles';
|
||||||
import Puzzle from '@/ui/Puzzle';
|
import Puzzle from '@/components/ui/Puzzle';
|
||||||
import SWRFallback from '@/ui/SWRFallback';
|
import SWRFallback from '@/components/ui/SWRFallback';
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
import Puzzles from '@/ui/Puzzles';
|
import Puzzles from '@/components/ui/Puzzles';
|
||||||
import SWRFallback from '@/ui/SWRFallback';
|
import SWRFallback from '@/components/ui/SWRFallback';
|
||||||
import { getPuzzles } from '@/lib/puzzles';
|
import { getPuzzles } from '@/lib/puzzles';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import '@/styles/globals.css';
|
import '@/styles/global.css';
|
||||||
import 'remixicon/fonts/remixicon.css';
|
|
||||||
|
|
||||||
import { type Metadata } from 'next';
|
import { type Metadata } from 'next';
|
||||||
import { Fira_Code } from 'next/font/google';
|
import { Fira_Code } from 'next/font/google';
|
||||||
|
@ -8,10 +7,13 @@ import { type ReactNode } from 'react';
|
||||||
|
|
||||||
import { cn, getURL } from '@/lib/utils';
|
import { cn, getURL } from '@/lib/utils';
|
||||||
|
|
||||||
|
import { ThemeProvider } from '@/components/ThemeProvider';
|
||||||
|
|
||||||
const sans = localFont({
|
const sans = localFont({
|
||||||
variable: '--font-sans',
|
variable: '--font-sans',
|
||||||
src: './fonts/Karrik.woff2',
|
src: './fonts/Karrik.woff2',
|
||||||
weight: 'variable'
|
weight: 'variable',
|
||||||
|
display: 'swap'
|
||||||
});
|
});
|
||||||
|
|
||||||
const code = Fira_Code({
|
const code = Fira_Code({
|
||||||
|
@ -28,26 +30,6 @@ export const metadata: Metadata = {
|
||||||
},
|
},
|
||||||
description: "Apprendre la programmation et la cybersécurité en s'amusant.",
|
description: "Apprendre la programmation et la cybersécurité en s'amusant.",
|
||||||
// manifest: getURL('/favicon/site.webmanifest'),
|
// manifest: getURL('/favicon/site.webmanifest'),
|
||||||
openGraph: {
|
|
||||||
title: {
|
|
||||||
default: 'Peer-at Code',
|
|
||||||
template: `%s - Peer-at Code`
|
|
||||||
},
|
|
||||||
description: "Apprendre la programmation et la cybersécurité en s'amusant.",
|
|
||||||
url: getURL(),
|
|
||||||
siteName: 'Peer-at Code',
|
|
||||||
// images: getURL('/assets/social.jpg'),
|
|
||||||
type: 'website'
|
|
||||||
},
|
|
||||||
twitter: {
|
|
||||||
card: 'summary_large_image',
|
|
||||||
title: {
|
|
||||||
default: 'Peer-at Code',
|
|
||||||
template: `%s - Peer-at Code`
|
|
||||||
},
|
|
||||||
description: "Apprendre la programmation et la cybersécurité en s'amusant."
|
|
||||||
// images: getURL('/assets/social.jpg'),
|
|
||||||
},
|
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: getURL()
|
canonical: getURL()
|
||||||
},
|
},
|
||||||
|
@ -74,14 +56,16 @@ export default function RootLayout({ children }: { children: ReactNode }) {
|
||||||
lang="fr"
|
lang="fr"
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
className={cn(
|
className={cn(
|
||||||
'scroll-smooth bg-gradient-to-b from-primary-800 to-primary-900 [color-scheme:dark]',
|
'scroll-smooth bg-gradient-to-b from-primary-800 to-primary-900',
|
||||||
sans.variable,
|
sans.variable,
|
||||||
code.variable
|
code.variable
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<head />
|
<head />
|
||||||
<body className="relative min-h-screen">
|
<body className="relative min-h-screen">
|
||||||
<main>{children}</main>
|
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
|
||||||
|
<main>{children}</main>
|
||||||
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import AppLink from '@/ui/AppLink';
|
import AppLink from '@/components/ui/AppLink';
|
||||||
import Console from '@/ui/Console';
|
import Console from '@/components/ui/Console';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
|
15
components.json
Normal file
15
components.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://ui.shadcn.com/schema.json",
|
||||||
|
"style": "default",
|
||||||
|
"rsc": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "tailwind.config.js",
|
||||||
|
"css": "styles/global.css",
|
||||||
|
"baseColor": "slate",
|
||||||
|
"cssVariables": true
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "@/components",
|
||||||
|
"utils": "@/lib/utils"
|
||||||
|
}
|
||||||
|
}
|
187
lib/hooks/use-toast.ts
Normal file
187
lib/hooks/use-toast.ts
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
// Inspired by react-hot-toast library
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import type { ToastActionElement, ToastProps } from '@/components/ui/Toast';
|
||||||
|
|
||||||
|
const TOAST_LIMIT = 1;
|
||||||
|
const TOAST_REMOVE_DELAY = 1000000;
|
||||||
|
|
||||||
|
type ToasterToast = ToastProps & {
|
||||||
|
id: string;
|
||||||
|
title?: React.ReactNode;
|
||||||
|
description?: React.ReactNode;
|
||||||
|
action?: ToastActionElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionTypes = {
|
||||||
|
ADD_TOAST: 'ADD_TOAST',
|
||||||
|
UPDATE_TOAST: 'UPDATE_TOAST',
|
||||||
|
DISMISS_TOAST: 'DISMISS_TOAST',
|
||||||
|
REMOVE_TOAST: 'REMOVE_TOAST'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
function genId() {
|
||||||
|
count = (count + 1) % Number.MAX_VALUE;
|
||||||
|
return count.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionType = typeof actionTypes;
|
||||||
|
|
||||||
|
type Action =
|
||||||
|
| {
|
||||||
|
type: ActionType['ADD_TOAST'];
|
||||||
|
toast: ToasterToast;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['UPDATE_TOAST'];
|
||||||
|
toast: Partial<ToasterToast>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['DISMISS_TOAST'];
|
||||||
|
toastId?: ToasterToast['id'];
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['REMOVE_TOAST'];
|
||||||
|
toastId?: ToasterToast['id'];
|
||||||
|
};
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
toasts: ToasterToast[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
|
||||||
|
|
||||||
|
const addToRemoveQueue = (toastId: string) => {
|
||||||
|
if (toastTimeouts.has(toastId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
toastTimeouts.delete(toastId);
|
||||||
|
dispatch({
|
||||||
|
type: 'REMOVE_TOAST',
|
||||||
|
toastId: toastId
|
||||||
|
});
|
||||||
|
}, TOAST_REMOVE_DELAY);
|
||||||
|
|
||||||
|
toastTimeouts.set(toastId, timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reducer = (state: State, action: Action): State => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'ADD_TOAST':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'UPDATE_TOAST':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t))
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'DISMISS_TOAST': {
|
||||||
|
const { toastId } = action;
|
||||||
|
|
||||||
|
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
||||||
|
// but I'll keep it here for simplicity
|
||||||
|
if (toastId) {
|
||||||
|
addToRemoveQueue(toastId);
|
||||||
|
} else {
|
||||||
|
state.toasts.forEach((toast) => {
|
||||||
|
addToRemoveQueue(toast.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.map((t) =>
|
||||||
|
t.id === toastId || toastId === undefined
|
||||||
|
? {
|
||||||
|
...t,
|
||||||
|
open: false
|
||||||
|
}
|
||||||
|
: t
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'REMOVE_TOAST':
|
||||||
|
if (action.toastId === undefined) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toasts: state.toasts.filter((t) => t.id !== action.toastId)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const listeners: Array<(state: State) => void> = [];
|
||||||
|
|
||||||
|
let memoryState: State = { toasts: [] };
|
||||||
|
|
||||||
|
function dispatch(action: Action) {
|
||||||
|
memoryState = reducer(memoryState, action);
|
||||||
|
listeners.forEach((listener) => {
|
||||||
|
listener(memoryState);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
type Toast = Omit<ToasterToast, 'id'>;
|
||||||
|
|
||||||
|
function toast({ ...props }: Toast) {
|
||||||
|
const id = genId();
|
||||||
|
|
||||||
|
const update = (props: ToasterToast) =>
|
||||||
|
dispatch({
|
||||||
|
type: 'UPDATE_TOAST',
|
||||||
|
toast: { ...props, id }
|
||||||
|
});
|
||||||
|
const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id });
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: 'ADD_TOAST',
|
||||||
|
toast: {
|
||||||
|
...props,
|
||||||
|
id,
|
||||||
|
open: true,
|
||||||
|
onOpenChange: (open: any) => {
|
||||||
|
if (!open) dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
dismiss,
|
||||||
|
update
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function useToast() {
|
||||||
|
const [state, setState] = React.useState<State>(memoryState);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
listeners.push(setState);
|
||||||
|
return () => {
|
||||||
|
const index = listeners.indexOf(setState);
|
||||||
|
if (index > -1) {
|
||||||
|
listeners.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [state]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
toast,
|
||||||
|
dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useToast, toast };
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { Icons, type Icon } from '@/components/ui/Icon';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A navigation item.
|
* A navigation item.
|
||||||
*
|
*
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const getPlayer = async ({
|
||||||
export type Player = {
|
export type Player = {
|
||||||
email: string;
|
email: string;
|
||||||
pseudo: string;
|
pseudo: string;
|
||||||
firstnames: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
description: string;
|
description: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
swcMinify: true,
|
swcMinify: true,
|
||||||
experimental: {
|
|
||||||
scrollRestoration: true
|
|
||||||
},
|
|
||||||
redirects: async () => {
|
redirects: async () => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
19
package.json
19
package.json
|
@ -20,25 +20,34 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/Peer-at-Code/peer-at-code#readme",
|
"homepage": "https://github.com/Peer-at-Code/peer-at-code#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@hookform/resolvers": "^3.1.0",
|
||||||
"@radix-ui/react-dialog": "^1.0.3",
|
"@radix-ui/react-dialog": "^1.0.3",
|
||||||
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-popover": "^1.0.5",
|
"@radix-ui/react-popover": "^1.0.5",
|
||||||
|
"@radix-ui/react-select": "^1.2.2",
|
||||||
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
"@radix-ui/react-toast": "^1.1.4",
|
||||||
"boring-avatars": "^1.7.0",
|
"boring-avatars": "^1.7.0",
|
||||||
|
"class-variance-authority": "^0.6.0",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"edge-csrf": "^1.0.3",
|
"edge-csrf": "^1.0.3",
|
||||||
"framer-motion": "^10.12.4",
|
"framer-motion": "^10.12.4",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"next": "13.4.0",
|
"lucide-react": "^0.252.0",
|
||||||
|
"next": "13.4.8",
|
||||||
|
"next-themes": "^0.2.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.43.1",
|
"react-hook-form": "^7.44.2",
|
||||||
"react-markdown": "^8.0.5",
|
"react-markdown": "^8.0.5",
|
||||||
"remark-breaks": "^3.0.2",
|
"remark-breaks": "^3.0.2",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remixicon": "^2.5.0",
|
"remixicon": "^3.3.0",
|
||||||
"sharp": "^0.32.1",
|
"sharp": "^0.32.1",
|
||||||
"swr": "^2.0.3",
|
"swr": "^2.0.3",
|
||||||
"tailwind-merge": "^1.9.0",
|
"tailwind-merge": "^1.12.0",
|
||||||
"zod": "^3.20.2"
|
"tailwindcss-animate": "^1.0.5",
|
||||||
|
"zod": "^3.21.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
|
|
2918
pnpm-lock.yaml
generated
2918
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
93
styles/global.css
Normal file
93
styles/global.css
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--muted: 210 40% 96.1%;
|
||||||
|
--muted-foreground: 215.4 16.3% 46.9%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--border: 214.3 31.8% 91.4%;
|
||||||
|
--input: 214.3 31.8% 91.4%;
|
||||||
|
|
||||||
|
--primary: 222.2 47.4% 11.2%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--secondary: 210 40% 96.1%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--ring: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 222.2 84% 4.9%;
|
||||||
|
--foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--muted: 217.2 32.6% 17.5%;
|
||||||
|
--muted-foreground: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--popover: 222.2 84% 4.9%;
|
||||||
|
--popover-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--card: 222.2 84% 4.9%;
|
||||||
|
--card-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--border: 217.2 32.6% 17.5%;
|
||||||
|
--input: 217.2 32.6% 17.5%;
|
||||||
|
|
||||||
|
--primary: 210 40% 98%;
|
||||||
|
--primary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--secondary: 217.2 32.6% 17.5%;
|
||||||
|
--secondary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--accent: 217.2 32.6% 17.5%;
|
||||||
|
--accent-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 0 85.7% 97.3%;
|
||||||
|
|
||||||
|
--ring: 217.2 32.6% 17.5%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.console {
|
||||||
|
@apply relative top-0.5 inline-block;
|
||||||
|
}
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:hover,
|
||||||
|
input:-webkit-autofill:focus,
|
||||||
|
textarea:-webkit-autofill,
|
||||||
|
textarea:-webkit-autofill:hover,
|
||||||
|
textarea:-webkit-autofill:focus {
|
||||||
|
-webkit-box-shadow: 0 0 0px 1000px hsl(258deg 15% 17%) inset;
|
||||||
|
transition: background-color 5000s ease-in-out 0s;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
@layer components {
|
|
||||||
.console {
|
|
||||||
@apply relative top-0.5 inline-block;
|
|
||||||
}
|
|
||||||
input:-webkit-autofill,
|
|
||||||
input:-webkit-autofill:hover,
|
|
||||||
input:-webkit-autofill:focus,
|
|
||||||
textarea:-webkit-autofill,
|
|
||||||
textarea:-webkit-autofill:hover,
|
|
||||||
textarea:-webkit-autofill:focus {
|
|
||||||
-webkit-box-shadow: 0 0 0px 1000px hsl(258deg 15% 17%) inset;
|
|
||||||
transition: background-color 5000s ease-in-out 0s;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,19 +3,60 @@ const defaultTheme = require('tailwindcss/defaultTheme');
|
||||||
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'jit',
|
darkMode: ['class'],
|
||||||
content: ['./app/**/*.{js,ts,jsx,tsx}', './ui/**/*.{js,ts,jsx,tsx}'],
|
content: [
|
||||||
future: {
|
'./pages/**/*.{ts,tsx}',
|
||||||
hoverOnlyWhenSupported: true
|
'./components/**/*.{ts,tsx}',
|
||||||
},
|
'./app/**/*.{ts,tsx}',
|
||||||
|
'./src/**/*.{ts,tsx}'
|
||||||
|
],
|
||||||
theme: {
|
theme: {
|
||||||
|
container: {
|
||||||
|
center: true,
|
||||||
|
padding: '2rem',
|
||||||
|
screens: {
|
||||||
|
'2xl': '1400px'
|
||||||
|
}
|
||||||
|
},
|
||||||
extend: {
|
extend: {
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: ['var(--font-sans)', ...defaultTheme.fontFamily.sans],
|
sans: ['var(--font-sans)', ...defaultTheme.fontFamily.sans],
|
||||||
code: ['var(--font-code)', ...defaultTheme.fontFamily.serif]
|
code: ['var(--font-code)', ...defaultTheme.fontFamily.serif]
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
...require('tailwindcss/colors'),
|
border: 'hsl(var(--border))',
|
||||||
|
input: 'hsl(var(--input))',
|
||||||
|
ring: 'hsl(var(--ring))',
|
||||||
|
background: 'hsl(var(--background))',
|
||||||
|
foreground: 'hsl(var(--foreground))',
|
||||||
|
primary: {
|
||||||
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
|
foreground: 'hsl(var(--primary-foreground))'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: 'hsl(var(--secondary))',
|
||||||
|
foreground: 'hsl(var(--secondary-foreground))'
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: 'hsl(var(--destructive))',
|
||||||
|
foreground: 'hsl(var(--destructive-foreground))'
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: 'hsl(var(--muted))',
|
||||||
|
foreground: 'hsl(var(--muted-foreground))'
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: 'hsl(var(--accent))',
|
||||||
|
foreground: 'hsl(var(--accent-foreground))'
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: 'hsl(var(--popover))',
|
||||||
|
foreground: 'hsl(var(--popover-foreground))'
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
DEFAULT: 'hsl(var(--card))',
|
||||||
|
foreground: 'hsl(var(--card-foreground))'
|
||||||
|
},
|
||||||
primary: {
|
primary: {
|
||||||
900: 'hsl(258deg 15% 7%)',
|
900: 'hsl(258deg 15% 7%)',
|
||||||
800: 'hsl(258deg 15% 11%)',
|
800: 'hsl(258deg 15% 11%)',
|
||||||
|
@ -83,8 +124,27 @@ module.exports = {
|
||||||
tertiary: 'hsl(258deg 8% 65%)',
|
tertiary: 'hsl(258deg 8% 65%)',
|
||||||
secondaryAccent: '#e2e8f0',
|
secondaryAccent: '#e2e8f0',
|
||||||
muted: 'hsl(258deg 7% 46%)'
|
muted: 'hsl(258deg 7% 46%)'
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
lg: 'var(--radius)',
|
||||||
|
md: 'calc(var(--radius) - 2px)',
|
||||||
|
sm: 'calc(var(--radius) - 4px)'
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
'accordion-down': {
|
||||||
|
from: { height: 0 },
|
||||||
|
to: { height: 'var(--radix-accordion-content-height)' }
|
||||||
|
},
|
||||||
|
'accordion-up': {
|
||||||
|
from: { height: 'var(--radix-accordion-content-height)' },
|
||||||
|
to: { height: 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||||
|
'accordion-up': 'accordion-up 0.2s ease-out'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [require('@tailwindcss/forms')]
|
plugins: [require('tailwindcss-animate'), require('tailwindcss'), require('autoprefixer')]
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue