infra(frontend): move frontend to seperate repository and add it as submodule If this initial code isn't going to be rewritten from scratch, it has to be clean enough to maintain, so moved the frontend to a seperate repository. Added it as a submodule for easier installation.
Brijesh ops@brijesh.dev
Thu, 04 Jul 2024 07:28:30 +0530
27 files changed,
3 insertions(+),
1024 deletions(-)
A
.gitmodules
@@ -0,0 +1,3 @@
+[submodule "frontend"] + path = frontend + url = https://github.com/wbrijesh/watchman-frontend
D
client/.gitignore
@@ -1,36 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts
D
client/next.config.mjs
@@ -1,6 +0,0 @@
-/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, -}; - -export default nextConfig;
D
client/package.json
@@ -1,32 +0,0 @@
-{ - "name": "client", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@headlessui/react": "^2.1.1", - "@headlessui/tailwindcss": "^0.2.1", - "@remixicon/react": "^4.2.0", - "@tremor/react": "^3.17.4", - "next": "14.2.4", - "react": "^18", - "react-dom": "^18", - "recharts": "^2.12.7" - }, - "devDependencies": { - "@tailwindcss/forms": "^0.5.7", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "eslint": "^8", - "eslint-config-next": "14.2.4", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "typescript": "^5" - } -}
D
client/postcss.config.mjs
@@ -1,8 +0,0 @@
-/** @type {import('postcss-load-config').Config} */ -const config = { - plugins: { - tailwindcss: {}, - }, -}; - -export default config;
D
client/src/api/projects.ts
@@ -1,78 +0,0 @@
-// type APIResponseType = { -// Status: string; -// Message: string; -// RequestID: string; -// Data: any; -// }; - -type ProjectType = { - ID?: string; - Name?: string; -}; - -async function CreatePorject( - projectObject: ProjectType, - setter: (response: any) => void, -) { - fetch("http://127.0.0.1:4000/projects", { - method: "POST", - body: JSON.stringify(projectObject), - }) - .then((res) => res.json()) - .then((data) => { - setter(data); - }); -} - -function ListProjects(setter: any) { - fetch("http://127.0.0.1:4000/projects") - .then((res) => res.json()) - .then((data) => { - setter(data); - }); -} - -function GetProjectById(projectID: string, setter: any) { - projectID && - fetch("http://127.0.0.1:4000/project?id=" + projectID) - .then((res) => res.json()) - .then((data) => { - setter(data); - }); -} - -function UpdateProject( - projectObject: ProjectType, - setter: (response: any) => void, -) { - fetch("http://127.0.0.1:4000/project", { - method: "PUT", - body: JSON.stringify(projectObject), - }) - .then((res) => res.json()) - .then((data) => { - setter(data); - }); -} - -function DeleteProject( - projectObject: ProjectType, - setter: (response: any) => void, -) { - fetch("http://127.0.0.1:4000/project", { - method: "DELETE", - body: JSON.stringify(projectObject), - }) - .then((res) => res.json()) - .then((data) => { - setter(data); - }); -} - -export { - CreatePorject, - ListProjects, - GetProjectById, - UpdateProject, - DeleteProject, -};
D
client/src/components/Breadcrumb.tsx
@@ -1,43 +0,0 @@
-import Link from "next/link"; -import { useRouter } from "next/router"; - -const Breadcrumb = () => { - const router = useRouter(); - return ( - <div className="bg-slate-100 py-1 px-2 border-b border-slate-200"> - {router.pathname.startsWith("/projects") && ( - <div className="flex gap-0.5 items-center"> - <p>/</p> - <Link className="hover:underline" href="/projects"> - Projects - </Link> - {router.pathname.replace("/projects", "") === "/create" && ( - <> - <p>/</p> - <Link className="hover:underline" href={"/projects/create"}> - Create Project - </Link> - </> - )} - {/* if path contains only one slash, it means page is project details */} - {(router.pathname.match(new RegExp("/", "g")) || []).length == 2 && - !router.pathname.includes("/create") && - !router.pathname.includes("/update") && - !router.pathname.includes("/delete") && ( - <> - <p>/</p> - <Link - className="hover:underline" - href={`/projects/${router.query.id}`} - > - Project Details - </Link> - </> - )} - </div> - )} - </div> - ); -}; - -export default Breadcrumb;
D
client/src/components/Button.tsx
@@ -1,32 +0,0 @@
-const PrimaryButton = ({ - text, - onClick = () => {}, - disabled = false, - type = "button", - intent = "primary", -}: { - text: string; - onClick?: () => void; - disabled?: boolean; - type?: "button" | "submit" | "reset"; - intent?: "primary" | "danger"; -}) => { - return ( - <div> - <button - onClick={onClick} - disabled={disabled} - type={type} - className={`text-white font-medium px-2 py-1 rounded ${ - intent === "primary" - ? "bg-slate-700 disabled:bg-slate-500" - : "bg-red-700 disabled:bg-red-500" - }`} - > - {text} - </button> - </div> - ); -}; - -export { PrimaryButton };
D
client/src/components/MainLayout.tsx
@@ -1,94 +0,0 @@
-import { Kode_Mono } from "next/font/google"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import Breadcrumb from "./Breadcrumb"; - -const LogoFont = Kode_Mono({ subsets: ["latin"] }); - -type SidebarOptionType = { - name: string; - link: string; -}; - -const SidebarOptions: SidebarOptionType[] = [ - { name: "Home", link: "/" }, - { name: "Projects", link: "/projects" }, - { name: "Logs", link: "/logs" }, - { name: "Metrics", link: "/metrics" }, - { name: "Analytics", link: "/analytics" }, -]; - -const BookmarkOptions: SidebarOptionType[] = [ - { name: "Example Project", link: "/projects/1" }, -]; - -const MainLayout = ({ children }: { children: React.ReactNode }) => { - const router = useRouter(); - return ( - <main className="text-slate-600 text-sm"> - <div className="flex"> - <div className="w-72 h-[calc(100vh-0px)] bg-white border-r border-slate-200 flex flex-col justify-between"> - <div> - <div className="h-14 w-full px-4 border-b border-slate-200 flex items-center justify-between"> - <div> - <p - className={`text-xl text-black font-semibold ${LogoFont.className}`} - > - WATCHMAN - </p> - </div> - </div> - <div className="flex flex-col"> - <div className="bg-slate-400 text-white text-xs font-bold py-0.5 px-3"> - MENU - </div> - {SidebarOptions.map((option) => ( - <Link - key={option.name} - href={`${option.link}`} - className={`border-b border-slate-200 py-2 px-3 hover:bg-slate-100 ${ - router.pathname.startsWith(option.link) && - option.link !== "/" - ? "bg-slate-200" - : "" - } ${ - router.pathname === option.link && option.link == "/" - ? "bg-slate-200" - : "" - }`} - > - {option.name} - </Link> - ))} - <div className="bg-slate-400 text-white text-xs font-bold py-0.5 px-3"> - BOOKMARKS - </div> - {BookmarkOptions.map((option) => ( - <Link - key={option.name} - href={option.link} - className={`border-b border-slate-200 py-2 px-3 hover:bg-slate-100 ${ - router.pathname == option.link ? "bg-slate-200" : "" - }`} - > - {option.name} - </Link> - ))} - </div> - </div> - - <div className="border-b border-slate-200 py-2 px-3"> - <p>Settings</p> - </div> - </div> - <div className="w-[calc(100vw-286px)]"> - <Breadcrumb /> - - <div className="p-4">{children}</div> - </div> - </div> - </main> - ); -}; - -export default MainLayout;
D
client/src/components/table.tsx
@@ -1,49 +0,0 @@
-export default function Table({ - columns, - data, -}: { - columns: string[]; - data: any[]; -}) { - return ( - <div> - <div className="flow-root"> - <div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"> - <div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8"> - <div className="overflow-hidden shadow ring-1 ring-slate-200 sm:-lg"> - <table className="min-w-full divide-y divide-slate-200"> - <thead className="bg-slate-100"> - <tr> - {columns.map((column: string) => ( - <th - key={column} - scope="col" - className="px-3 py-2 text-left text-sm font-semibold text-slate-500" - > - {column} - </th> - ))} - </tr> - </thead> - <tbody className="divide-y divide-slate-200 bg-white"> - {data.map((row: any) => ( - <tr key={row.id}> - {columns.map((column: string) => ( - <td - key={column} - className="whitespace-nowrap py-2 px-3 text-sm text-slate-600" - > - {row[column.toLowerCase()]} - </td> - ))} - </tr> - ))} - </tbody> - </table> - </div> - </div> - </div> - </div> - </div> - ); -}
D
client/src/components/visualisation/Bar-Chart.tsx
@@ -1,124 +0,0 @@
-import { BarChart, Card, Divider, Switch } from "@tremor/react"; -import { useState } from "react"; - -function valueFormatter(number: any) { - return new Intl.NumberFormat("en-US", { - maximumFractionDigits: 0, - notation: "compact", - compactDisplay: "short", - style: "currency", - currency: "INR", - }).format(number); -} - -export default function BarChartExample() { - const [showComparison, setShowComparison] = useState(false); - return ( - <> - {/* <Card className="ax-w-2xl"> */} - <BarChart - data={data} - index="date" - categories={["value"]} - colors={["slate"]} - valueFormatter={valueFormatter} - showYAxis={false} - className="my-4 h-40" - showLegend={false} - showGridLines={false} - showAnimation={true} - animationDuration={100} - tickGap={30} - barCategoryGap={3} - /> - {/* </Card> */} - </> - ); -} - -const data = [ - { date: "May 23", value: 56000 }, - { date: "Jun 23", value: 30000 }, - { date: "Jul 23", value: 85390 }, - { date: "Aug 23", value: 80100 }, - { date: "Sep 23", value: 75090 }, - { date: "Oct 23", value: 71080 }, - { date: "Nov 23", value: 61210 }, - { date: "Dec 23", value: 60143 }, - { date: "Jan 24", value: 10000 }, - { date: "Feb 24", value: 10000 }, - { date: "Mar 24", value: 10000 }, - { date: "Apr 24", value: 10000 }, - { date: "May 24", value: 10000 }, - { date: "Jun 24", value: 10000 }, - { date: "Jul 24", value: 10000 }, - { date: "Aug 24", value: 10000 }, - { date: "Sep 24", value: 10000 }, - { date: "Oct 24", value: 10000 }, - { date: "Nov 24", value: 10000 }, - { date: "Dec 24", value: 10000 }, - { date: "Jan 25", value: 10000 }, - { date: "Feb 25", value: 10000 }, - { date: "Mar 25", value: 10000 }, - { date: "Apr 25", value: 10000 }, - { date: "May 25", value: 10000 }, - { date: "Jun 25", value: 10000 }, - { date: "Jul 25", value: 10000 }, - { date: "Aug 25", value: 10000 }, - { date: "Sep 25", value: 10000 }, - { date: "Oct 25", value: 10000 }, - { date: "Nov 25", value: 10000 }, - { date: "Dec 25", value: 10000 }, - { date: "Jan 26", value: 10000 }, - { date: "Feb 26", value: 10000 }, - { date: "Mar 26", value: 10000 }, - { date: "Apr 26", value: 10000 }, - { date: "May 26", value: 10000 }, - { date: "Jun 26", value: 10000 }, - { date: "Jul 26", value: 10000 }, - { date: "Aug 26", value: 10000 }, - { date: "Sep 26", value: 10000 }, - { date: "Oct 26", value: 10000 }, - { date: "Nov 26", value: 10000 }, - { date: "Dec 26", value: 10000 }, - { date: "Jan 27", value: 10000 }, - { date: "Feb 27", value: 10000 }, - { date: "Mar 27", value: 10000 }, - { date: "Apr 27", value: 10000 }, - { date: "May 27", value: 10000 }, - { date: "Jun 27", value: 10000 }, - { date: "Jul 27", value: 43523 }, - { date: "Aug 27", value: 10000 }, - { date: "Sep 27", value: 10000 }, - { date: "Oct 27", value: 10000 }, - { date: "Nov 27", value: 10000 }, - { date: "Dec 27", value: 10000 }, - { date: "Jan 28", value: 10000 }, - { date: "Feb 28", value: 10000 }, - { date: "Mar 28", value: 10000 }, - { date: "Apr 28", value: 10000 }, - { date: "May 28", value: 10000 }, - { date: "Jun 28", value: 10000 }, - { date: "Jul 28", value: 10000 }, - { date: "Aug 28", value: 10000 }, - { date: "Sep 28", value: 10000 }, - { date: "Oct 28", value: 10000 }, - { date: "Nov 28", value: 10000 }, - { date: "Dec 28", value: 10000 }, - { date: "Jan 29", value: 10000 }, - { date: "Feb 29", value: 10000 }, - { date: "Mar 29", value: 10000 }, - { date: "Apr 29", value: 10000 }, - { date: "May 29", value: 10000 }, - { date: "Jun 29", value: 10000 }, - { date: "Jul 29", value: 10000 }, - { date: "Aug 29", value: 10000 }, - { date: "Sep 29", value: 10000 }, - { date: "Oct 29", value: 10000 }, - { date: "Nov 29", value: 10000 }, - { date: "Dec 29", value: 10000 }, - { date: "Jan 30", value: 10000 }, - { date: "Feb 30", value: 10000 }, - { date: "Mar 30", value: 10000 }, - { date: "Apr 30", value: 10000 }, -];
D
client/src/pages/_app.tsx
@@ -1,6 +0,0 @@
-import "@/styles/globals.css"; -import type { AppProps } from "next/app"; - -export default function App({ Component, pageProps }: AppProps) { - return <Component {...pageProps} />; -}
D
client/src/pages/_document.tsx
@@ -1,13 +0,0 @@
-import { Html, Head, Main, NextScript } from "next/document"; - -export default function Document() { - return ( - <Html lang="en"> - <Head /> - <body> - <Main /> - <NextScript /> - </body> - </Html> - ); -}
D
client/src/pages/api/hello.ts
@@ -1,13 +0,0 @@
-// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from "next"; - -type Data = { - name: string; -}; - -export default function handler( - req: NextApiRequest, - res: NextApiResponse<Data>, -) { - res.status(200).json({ name: "John Doe" }); -}
D
client/src/pages/index.tsx
@@ -1,26 +0,0 @@
-import MainLayout from "@/components/MainLayout"; -import BarChartExample from "@/components/visualisation/Bar-Chart"; -import { BarChart } from "@tremor/react"; -import Head from "next/head"; -import Link from "next/link"; - -const Homepage = () => { - return ( - <MainLayout> - <Head> - <title>Watchman</title> - <Link - rel="icon" - href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎯</text></svg>" - /> - </Head> - <h1 className="text-xl font-medium">Homepage</h1> - <p className="my-2"> - Please check this page later, as it is still under construction. - </p> - <BarChartExample /> - </MainLayout> - ); -}; - -export default Homepage;
D
client/src/pages/logs/index.tsx
@@ -1,23 +0,0 @@
-import MainLayout from "@/components/MainLayout"; -import Head from "next/head"; -import Link from "next/link"; - -const LogsIndexPage = () => { - return ( - <MainLayout> - <Head> - <title>Watchman</title> - <Link - rel="icon" - href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎯</text></svg>" - /> - </Head> - <h1 className="text-xl font-medium">Logs Index Page</h1> - <p className="my-2"> - Please check this page later, as it is still under construction. - </p> - </MainLayout> - ); -}; - -export default LogsIndexPage;
D
client/src/pages/projects/[id]/delete.tsx
@@ -1,53 +0,0 @@
-import { DeleteProject, GetProjectById, ListProjects } from "@/api/projects"; -import { PrimaryButton } from "@/components/Button"; -import MainLayout from "@/components/MainLayout"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const ProjectDeletePage = () => { - const router = useRouter(); - const { id } = router.query; - - const [project, setProject] = useState<any>(); - const [apiResponse, setApiResponse] = useState<any>(); - - useEffect(() => { - GetProjectById(id ? id.toString() : "", setProject); - }, [id]); - - function deleteProject() { - let project = { ID: id ? id.toString() : "" }; - - DeleteProject(project, setApiResponse); - } - - useEffect(() => { - apiResponse && apiResponse.status === "OK" && router.push("/projects"); - }, [apiResponse]); - - return ( - <MainLayout> - <Head> - <title>Delete Project | Watchman</title> - </Head> - <div className="mb-4 flex justify-between items-center uppercase"> - {project?.data?.name && ( - <h1 className="text-xl font-medium">{project.data.name}</h1> - )} - </div> - {project && project.data && project.data.name && ( - <p>Are you sure you want to delete this {project.data.name} project?</p> - )} - <div className="my-4 flex gap-2"> - <PrimaryButton - text="Delete" - intent="danger" - onClick={() => deleteProject()} - /> - <PrimaryButton text="Cancel" onClick={() => router.push("/projects")} /> - </div> - </MainLayout> - ); -}; -export default ProjectDeletePage;
D
client/src/pages/projects/[id]/index.tsx
@@ -1,54 +0,0 @@
-import { GetProjectById, ListProjects } from "@/api/projects"; -import { PrimaryButton } from "@/components/Button"; -import MainLayout from "@/components/MainLayout"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const ProjectDetailsPage = () => { - const router = useRouter(); - const { id } = router.query; - - const [project, setProject] = useState<any>(); - - useEffect(() => { - GetProjectById(id ? id.toString() : "", setProject); - }, [id]); - - return ( - <MainLayout> - <Head> - <title>Project Details | Watchman</title> - </Head> - <div className="mb-4 flex justify-between items-center uppercase"> - {project?.data?.name && ( - <h1 className="text-xl font-medium">{project.data.name}</h1> - )} - <div className="flex items-center gap-2"> - <PrimaryButton - text="Update" - onClick={() => router.push("/projects/" + id + "/update")} - /> - <PrimaryButton - text="Delete" - intent="danger" - onClick={() => router.push("/projects/" + id + "/delete")} - /> - </div> - </div> - {project && project.data && project.data.name && ( - <> - <div className="flex justify-start"> - <div className="w-48">Name</div> - <p>{project.data.name}</p> - </div> - <div className="flex justify-start"> - <div className="w-48">ID</div> - <p>{project.data.id}</p> - </div> - </> - )} - </MainLayout> - ); -}; -export default ProjectDetailsPage;
D
client/src/pages/projects/[id]/update.tsx
@@ -1,57 +0,0 @@
-import { GetProjectById, UpdateProject } from "@/api/projects"; -import { PrimaryButton } from "@/components/Button"; -import MainLayout from "@/components/MainLayout"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const UpdateProjectPage = () => { - const router = useRouter(); - const { id } = router.query; - - const [project, setProject] = useState<any>(); - - useEffect(() => { - GetProjectById(id ? id.toString() : "", setProject); - }, [id]); - - const [name, setName] = useState(project?.data?.name || ""); - const [apiResponse, setApiResponse] = useState<any>(); - - async function formSubmit(e: React.FormEvent) { - e.preventDefault(); - let project = { Name: name, Id: id }; - - UpdateProject(project, setApiResponse); - } - - useEffect(() => { - apiResponse && apiResponse.status === "OK" && router.push("/projects"); - }, [apiResponse]); - - useEffect(() => { - setName(project?.data?.name || ""); - }, [project]); - - return ( - <MainLayout> - <Head> - <title>Update Project | Watchman</title> - </Head> - <h1 className="text-xl font-medium">Update Project</h1> - - <form onSubmit={formSubmit} className="my-4 flex flex-col gap-4"> - <div> - <label className="block text-sm font-medium">Name</label> - <input - value={name} - onChange={(e) => setName(e.target.value)} - className="w-80 border border-slate-200 p-1" - /> - </div> - <PrimaryButton type="submit" text="Update Project" /> - </form> - </MainLayout> - ); -}; -export default UpdateProjectPage;
D
client/src/pages/projects/create.tsx
@@ -1,46 +0,0 @@
-import { CreatePorject } from "@/api/projects"; -import { PrimaryButton } from "@/components/Button"; -import MainLayout from "@/components/MainLayout"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const CreateProjectPage = () => { - const router = useRouter(); - - const [name, setName] = useState(""); - const [apiResponse, setApiResponse] = useState<any>(); - - async function formSubmit(e: React.FormEvent) { - e.preventDefault(); - let project = { Name: name }; - - CreatePorject(project, setApiResponse); - } - - useEffect(() => { - apiResponse && apiResponse.status === "OK" && router.push("/projects"); - }, [apiResponse]); - - return ( - <MainLayout> - <Head> - <title>Create Projects | Watchman</title> - </Head> - <h1 className="text-xl font-medium">Create Project</h1> - - <form onSubmit={formSubmit} className="my-4 flex flex-col gap-4"> - <div> - <label className="block text-sm font-medium">Name</label> - <input - value={name} - onChange={(e) => setName(e.target.value)} - className="w-80 border border-slate-200 p-1" - /> - </div> - <PrimaryButton type="submit" text="Create Project" /> - </form> - </MainLayout> - ); -}; -export default CreateProjectPage;
D
client/src/pages/projects/index.tsx
@@ -1,47 +0,0 @@
-import { ListProjects } from "@/api/projects"; -import { PrimaryButton } from "@/components/Button"; -import MainLayout from "@/components/MainLayout"; -import Table from "@/components/table"; -import Head from "next/head"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const ProjectsHomePage = () => { - const router = useRouter(); - - const [projects, setProjects] = useState<any>([]); - - useEffect(() => { - ListProjects(setProjects); - }, []); - - return ( - <MainLayout> - <Head> - <title>Projects | Watchman</title> - </Head> - <div className="mb-4 flex justify-between items-center"> - <h1 className="text-xl font-medium">Projects</h1> - <PrimaryButton - text="Create Project" - onClick={() => router.push("/projects/create")} - /> - </div> - {projects.data !== undefined && ( - <Table - columns={["Name", "ID"]} - data={projects.data.map((project: any) => { - return { - name: ( - <Link href={"/projects/" + project.id}>{project.name}</Link> - ), - id: project.id, - }; - })} - /> - )} - </MainLayout> - ); -}; -export default ProjectsHomePage;
D
client/src/styles/globals.css
@@ -1,3 +0,0 @@
-@tailwind base; -@tailwind components; -@tailwind utilities;
D
client/tailwind.config.ts
@@ -1,157 +0,0 @@
-// import type { Config } from "tailwindcss"; -// -// const config: Config = { -// content: [ -// "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", -// "./src/components/**/*.{js,ts,jsx,tsx,mdx}", -// "./src/app/**/*.{js,ts,jsx,tsx,mdx}", -// ], -// theme: { -// extend: { -// backgroundImage: { -// "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", -// "gradient-conic": -// "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", -// }, -// }, -// }, -// plugins: [], -// }; -// export default config; - -import type { Config } from "tailwindcss"; -import colors from "tailwindcss/colors"; - -const config: Config = { - content: [ - "./src/**/*.{js,ts,jsx,tsx}", - - // Path to Tremor module - "./node_modules/@tremor/**/*.{js,ts,jsx,tsx}", - ], - theme: { - transparent: "transparent", - current: "currentColor", - extend: { - colors: { - // light mode - tremor: { - brand: { - faint: colors.blue[50], - muted: colors.blue[200], - subtle: colors.blue[400], - DEFAULT: colors.blue[500], - emphasis: colors.blue[700], - inverted: colors.white, - }, - background: { - muted: colors.gray[50], - subtle: colors.gray[100], - DEFAULT: colors.white, - emphasis: colors.gray[700], - }, - border: { - DEFAULT: colors.gray[200], - }, - ring: { - DEFAULT: colors.gray[200], - }, - content: { - subtle: colors.gray[400], - DEFAULT: colors.gray[500], - emphasis: colors.gray[700], - strong: colors.gray[900], - inverted: colors.white, - }, - }, - // dark mode - // "dark-tremor": { - // brand: { - // faint: "#0B1229", - // muted: colors.blue[950], - // subtle: colors.blue[800], - // DEFAULT: colors.blue[500], - // emphasis: colors.blue[400], - // inverted: colors.blue[950], - // }, - // background: { - // muted: "#131A2B", - // subtle: colors.gray[800], - // DEFAULT: colors.gray[900], - // emphasis: colors.gray[300], - // }, - // border: { - // DEFAULT: colors.gray[800], - // }, - // ring: { - // DEFAULT: colors.gray[800], - // }, - // content: { - // subtle: colors.gray[600], - // DEFAULT: colors.gray[500], - // emphasis: colors.gray[200], - // strong: colors.gray[50], - // inverted: colors.gray[950], - // }, - // }, - }, - boxShadow: { - // light - "tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", - "tremor-card": - "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", - "tremor-dropdown": - "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", - // dark - // "dark-tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", - // "dark-tremor-card": - // "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", - // "dark-tremor-dropdown": - // "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", - }, - borderRadius: { - "tremor-small": "0.375rem", - "tremor-default": "0.2rem", - "tremor-full": "9999px", - }, - fontSize: { - "tremor-label": ["0.75rem", { lineHeight: "1rem" }], - "tremor-default": ["0.875rem", { lineHeight: "1.25rem" }], - "tremor-title": ["1.125rem", { lineHeight: "1.75rem" }], - "tremor-metric": ["1.875rem", { lineHeight: "2.25rem" }], - }, - }, - }, - safelist: [ - { - pattern: - /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - variants: ["hover", "ui-selected"], - }, - { - pattern: - /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - variants: ["hover", "ui-selected"], - }, - { - pattern: - /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - variants: ["hover", "ui-selected"], - }, - { - pattern: - /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - }, - { - pattern: - /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - }, - { - pattern: - /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, - }, - ], - plugins: [require("@headlessui/tailwindcss"), require("@tailwindcss/forms")], -}; - -export default config;
D
client/tsconfig.json
@@ -1,21 +0,0 @@
-{ - "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] -}