master 630988faa7ee cached
160 files
266.0 KB
77.5k tokens
236 symbols
1 requests
Download .txt
Showing preview only (307K chars total). Download the full file or copy to clipboard to get everything.
Repository: SashenJayathilaka/ChatGPT-Clone
Branch: master
Commit: 630988faa7ee
Files: 160
Total size: 266.0 KB

Directory structure:
gitextract__q2wgi47/

├── README.md
├── aws-bucket-policy.json
├── client/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierrc
│   ├── README.md
│   ├── app/
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   ├── loading.tsx
│   │   ├── page.tsx
│   │   ├── priority/
│   │   │   ├── backlog/
│   │   │   │   └── page.tsx
│   │   │   ├── high/
│   │   │   │   └── page.tsx
│   │   │   ├── low/
│   │   │   │   └── page.tsx
│   │   │   ├── medium/
│   │   │   │   └── page.tsx
│   │   │   └── urgent/
│   │   │       └── page.tsx
│   │   ├── projects/
│   │   │   └── [id]/
│   │   │       └── page.tsx
│   │   ├── search/
│   │   │   └── page.tsx
│   │   ├── settings/
│   │   │   └── page.tsx
│   │   ├── teams/
│   │   │   └── page.tsx
│   │   ├── timeline/
│   │   │   └── page.tsx
│   │   └── users/
│   │       └── page.tsx
│   ├── components/
│   │   ├── Header/
│   │   │   └── index.tsx
│   │   ├── data/
│   │   │   └── columns.tsx
│   │   ├── global/
│   │   │   ├── auth-provider/
│   │   │   │   └── index.tsx
│   │   │   ├── border-view/
│   │   │   │   └── index.tsx
│   │   │   ├── loader/
│   │   │   │   └── spinner.tsx
│   │   │   ├── project-header/
│   │   │   │   └── index.tsx
│   │   │   ├── tab-button/
│   │   │   │   └── index.tsx
│   │   │   ├── task/
│   │   │   │   └── index.tsx
│   │   │   ├── task-card/
│   │   │   │   └── index.tsx
│   │   │   └── task-column/
│   │   │       └── index.tsx
│   │   ├── home-page/
│   │   │   └── index.tsx
│   │   ├── list-view/
│   │   │   └── index.tsx
│   │   ├── modal/
│   │   │   ├── index.tsx
│   │   │   ├── modal-new-project/
│   │   │   │   └── index.tsx
│   │   │   └── model-new-task/
│   │   │       └── index.tsx
│   │   ├── navbar/
│   │   │   └── index.tsx
│   │   ├── priorityPage/
│   │   │   └── index.tsx
│   │   ├── project-card/
│   │   │   └── index.tsx
│   │   ├── project-page/
│   │   │   └── index.tsx
│   │   ├── search-page/
│   │   │   └── index.tsx
│   │   ├── settings-page/
│   │   │   └── index.tsx
│   │   ├── sidebar/
│   │   │   └── index.tsx
│   │   ├── table-view/
│   │   │   └── index.tsx
│   │   ├── team-page/
│   │   │   └── index.tsx
│   │   ├── timeline/
│   │   │   └── index.tsx
│   │   ├── timeline-view/
│   │   │   └── index.tsx
│   │   ├── user-card/
│   │   │   └── index.tsx
│   │   ├── user-page/
│   │   │   └── index.tsx
│   │   └── wrapper/
│   │       ├── dashboardWrapper.tsx
│   │       └── redux.tsx
│   ├── lib/
│   │   └── utils.ts
│   ├── next.config.mjs
│   ├── package.json
│   ├── postcss.config.mjs
│   ├── state/
│   │   ├── api.ts
│   │   └── index.ts
│   ├── tailwind.config.ts
│   ├── tsconfig.json
│   └── types/
│       └── type.ts
├── lamda_trigger.mjs
├── production-level-application/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── README.md
│   ├── actions/
│   │   └── index.ts
│   ├── app/
│   │   ├── (auth)/
│   │   │   ├── layout.tsx
│   │   │   ├── sign-in/
│   │   │   │   └── [[...sign-in]]/
│   │   │   │       └── page.tsx
│   │   │   └── sign-up/
│   │   │       └── [[...sign-up]]/
│   │   │           └── page.tsx
│   │   ├── api/
│   │   │   ├── move/
│   │   │   │   └── [taskId]/
│   │   │   │       └── route.tsx
│   │   │   ├── projects/
│   │   │   │   ├── [projectId]/
│   │   │   │   │   └── route.ts
│   │   │   │   └── route.ts
│   │   │   ├── tasks/
│   │   │   │   ├── [projectId]/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── route.ts
│   │   │   │   └── user/
│   │   │   │       └── [userId]/
│   │   │   │           └── route.ts
│   │   │   └── user/
│   │   │       ├── [userId]/
│   │   │       │   └── route.ts
│   │   │       └── route.ts
│   │   ├── dashboard/
│   │   │   ├── layout.tsx
│   │   │   ├── loading.tsx
│   │   │   ├── page.tsx
│   │   │   ├── priority/
│   │   │   │   ├── backlog/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── high/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── low/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── medium/
│   │   │   │   │   └── page.tsx
│   │   │   │   └── urgent/
│   │   │   │       └── page.tsx
│   │   │   ├── projects/
│   │   │   │   └── [id]/
│   │   │   │       └── page.tsx
│   │   │   └── timeline/
│   │   │       └── page.tsx
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   ├── loading.tsx
│   │   └── page.tsx
│   ├── components/
│   │   ├── data/
│   │   │   └── columns.tsx
│   │   ├── global/
│   │   │   ├── border-view/
│   │   │   │   └── index.tsx
│   │   │   ├── client-only/
│   │   │   │   └── index.tsx
│   │   │   ├── image-card/
│   │   │   │   └── index.tsx
│   │   │   ├── image-upload/
│   │   │   │   └── index.tsx
│   │   │   ├── list-view/
│   │   │   │   └── index.tsx
│   │   │   ├── loader/
│   │   │   │   ├── buttonLoader.tsx
│   │   │   │   └── spinner.tsx
│   │   │   ├── project-header/
│   │   │   │   └── index.tsx
│   │   │   ├── project-page/
│   │   │   │   └── index.tsx
│   │   │   ├── tab-button/
│   │   │   │   └── index.tsx
│   │   │   ├── table-view/
│   │   │   │   └── index.tsx
│   │   │   ├── task-card/
│   │   │   │   └── index.tsx
│   │   │   ├── task-column/
│   │   │   │   └── index.tsx
│   │   │   └── timeline-view/
│   │   │       └── index.tsx
│   │   ├── header/
│   │   │   └── index.tsx
│   │   ├── home-page/
│   │   │   ├── index.tsx
│   │   │   └── root-home-page/
│   │   │       └── index.tsx
│   │   ├── modal/
│   │   │   ├── index.tsx
│   │   │   ├── modal-new-project/
│   │   │   │   └── index.tsx
│   │   │   ├── model-new-task/
│   │   │   │   └── index.tsx
│   │   │   └── model-share-project/
│   │   │       └── index.tsx
│   │   ├── navbar/
│   │   │   ├── home/
│   │   │   │   └── index.tsx
│   │   │   └── index.tsx
│   │   ├── priority-page/
│   │   │   └── index.tsx
│   │   ├── sidebar/
│   │   │   └── index.tsx
│   │   ├── task/
│   │   │   └── index.tsx
│   │   ├── timeline/
│   │   │   └── index.tsx
│   │   └── wrapper/
│   │       ├── dashboardWrapper.tsx
│   │       └── redux.tsx
│   ├── lib/
│   │   ├── prismadb.ts
│   │   └── utils.ts
│   ├── middleware.ts
│   ├── next.config.mjs
│   ├── package.json
│   ├── postcss.config.mjs
│   ├── prisma/
│   │   └── schema.prisma
│   ├── provider/
│   │   └── reduxProvider.tsx
│   ├── state/
│   │   ├── api.ts
│   │   └── index.ts
│   ├── tailwind.config.ts
│   ├── tsconfig.json
│   └── types/
│       └── type.ts
└── server/
    ├── .gitignore
    ├── ecosystem.config.js
    ├── package.json
    ├── prisma/
    │   ├── migrations/
    │   │   ├── 20250103002536_init/
    │   │   │   └── migration.sql
    │   │   └── migration_lock.toml
    │   ├── schema.prisma
    │   ├── seed.ts
    │   └── seedData/
    │       ├── attachment.json
    │       ├── comment.json
    │       ├── project.json
    │       ├── projectTeam.json
    │       ├── task.json
    │       ├── taskAssignment.json
    │       ├── team.json
    │       └── user.json
    ├── src/
    │   ├── controllers/
    │   │   ├── projectControllers.ts
    │   │   ├── searchControllers.ts
    │   │   ├── taskControllers.ts
    │   │   ├── teamControllers.ts
    │   │   └── usercontrollers.ts
    │   ├── index.ts
    │   └── routes/
    │       ├── projectRoutes.ts
    │       ├── searchRoutes.ts
    │       ├── taskRoute.ts
    │       ├── teamRoutes.ts
    │       └── userRoutes.ts
    └── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
<div align="center">

<img src="https://png.pngtree.com/png-vector/20220706/ourmid/pngtree-project-management-png-image_5687733.png" alt="logo" width="250" />

# 🗂️ Project Management App (Full Stack + AWS)

This is a **Project Management Dashboard** built using modern web technologies. It includes a powerful frontend, a backend server, and secure cloud integration with AWS. Perfect for managing tasks, tracking projects, and working with teams.

</div>

---

### 🚀 Live Demo

👉 [View the App Live](https://pm-app-tan.vercel.app/)

---

### 📚 Table of Contents

* [About](#about)
* [Features](#features)
* [Tech Stack](#tech-stack)
* [Screenshots](#screenshots)
* [Getting Started](#getting-started)

  * [Requirements](#requirements)
  * [Installation](#installation)
  * [Running Locally](#running-locally)
  * [Environment Variables](#environment-variables)
* [Deployment](#deployment)
* [Contact](#contact)

---

## 📌 About

This app is a **full-stack project management tool**. It helps teams stay organized with features like task tracking, user authentication, cloud hosting, and more.

---

## ✨ Features

✅ Create and manage projects
✅ Add tasks and assign team members
✅ User authentication (with AWS Cognito)
✅ Cloud functions using AWS Lambda
✅ Beautiful UI with charts and data tables

---

## 🛠 Tech Stack

### Frontend

* Next.js
* TypeScript
* React.js
* Tailwind CSS
* Material UI Data Grid

### Backend

* Node.js
* Express.js
* PostgreSQL
* Prisma ORM

### Cloud & DevOps

* AWS Lambda
* AWS Cognito
* Vercel (Deployment)

---

## 📷 Screenshots

> Here’s a preview of the dashboard (Click to view):

<div align="center">
<a href="https://pm-app-tan.vercel.app/"><img src="https://github.com/user-attachments/assets/6e7f768d-d7a0-4b63-bc08-a1419efad1b0" alt="screenshot" width="600"/></a>
</div>

---

## 🧰 Getting Started

### ✅ Requirements

Before you start, make sure you have:

* [Node.js](https://nodejs.org/en/) installed
* An [AWS account](https://aws.amazon.com/free/)
* A [Clerk account](https://clerk.com/) for user auth (optional but recommended)

---

### 📦 Installation

Clone the project:

```bash
git clone https://github.com/SashenJayathilaka/Project-Management-App.git
cd Project-Management-App
```

Install the dependencies:

```bash
npm install
```

---

### 🧪 Running Locally

To start the app locally:

```bash
npm run dev
```

Then open your browser and go to:
👉 [http://localhost:3000](http://localhost:3000)

---

### 🔐 Environment Variables

Create a `.env` file in the root directory and add the required keys.

Example:

```env
DATABASE_URL=your_postgres_db_url
AWS_REGION=your_aws_region
COGNITO_USER_POOL_ID=your_cognito_pool_id
COGNITO_CLIENT_ID=your_cognito_client_id
```

---

## 🚀 Deployment

### Deploy with Vercel

The easiest way to deploy is using **Vercel**:

1. Go to [https://vercel.com/new](https://vercel.com/new)
2. Import your GitHub repository
3. Add environment variables in the Vercel dashboard
4. Deploy and enjoy!

You can also deploy manually using other platforms like AWS, Netlify, or Docker.

---

## 📬 Contact

**Developer**: Sashen Jayathilaka
📧 Email: [sashenjayathilaka95@gmail.com](mailto:sashenjayathilaka95@gmail.com)
🐦 Twitter: [@SashenHasinduJ](https://twitter.com/SashenHasinduJ)

🔗 Project Repository: [GitHub Link](https://github.com/SashenJayathilaka/Project-Management-App.git)

---

<div align="center">
⭐️ If you found this project helpful, feel free to star it!
</div>


================================================
FILE: aws-bucket-policy.json
================================================
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "*"
        }
    ]
}

================================================
FILE: client/.eslintrc.json
================================================
{
  "extends": "next/core-web-vitals"
}


================================================
FILE: client/.gitignore
================================================
# 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


================================================
FILE: client/.prettierrc
================================================
{
  "plugins": ["prettier-plugin-tailwindcss"]
}


================================================
FILE: client/README.md
================================================
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.


================================================
FILE: client/app/globals.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body,
#root,
.app {
  height: 100%;
  width: 100%;
  @apply text-sm;
  @apply bg-gray-500;
  @apply text-gray-900;
}

.timeline ._3_ygE {
  @apply rounded-tl-md border border-r-0 border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._2eZzQ {
  @apply border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._2dZTy {
  @apply fill-white dark:fill-dark-secondary;
}
.timeline ._2dZTy:nth-child(even) {
  @apply fill-[#f5f5f5] dark:fill-dark-tertiary;
}
.timeline ._35nLX {
  @apply fill-white stroke-[#e6e4e4] dark:fill-dark-secondary dark:stroke-stroke-dark;
}
.timeline ._9w8d5 {
  @apply fill-[#333] dark:fill-white;
}
.timeline ._34SS0 {
  @apply bg-white dark:bg-dark-secondary;
}
.timeline ._34SS0:nth-of-type(even) {
  @apply bg-[#f5f5f5] dark:bg-dark-tertiary;
}
.timeline ._RuwuK,
.timeline ._3rUKi,
.timeline ._1rLuZ {
  @apply stroke-[#e6e4e4] dark:stroke-stroke-dark;
}
.timeline ._3ZbQT {
  @apply border-l-0 border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._3T42e {
  @apply bg-white dark:bg-dark-bg;
}
.timeline ._29NTg {
  @apply dark:text-neutral-500;
}

::-webkit-scrollbar {
  width: 0px;
  height: 0px;
}


================================================
FILE: client/app/layout.tsx
================================================
import DashboardWrapper from "@/components/wrapper/dashboardWrapper";
import type { Metadata } from "next";
import { Plus_Jakarta_Sans } from "next/font/google";
import "./globals.css";

const jakarta = Plus_Jakarta_Sans({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={jakarta.className}>
        <DashboardWrapper>{children}</DashboardWrapper>
      </body>
    </html>
  );
}


================================================
FILE: client/app/loading.tsx
================================================
import { Spinner } from "@/components/global/loader/spinner";

type Props = {};

function Loading({}: Props) {
  return (
    <div className="flex h-screen items-center justify-center">
      <Spinner />
    </div>
  );
}

export default Loading;


================================================
FILE: client/app/page.tsx
================================================
import HomePage from "@/components/home-page";

export default function Home() {
  return <HomePage />;
}


================================================
FILE: client/app/priority/backlog/page.tsx
================================================
import PriorityPage from "@/components/priorityPage";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return <PriorityPage priority={Priority.Backlog} />;
}

export default Page;


================================================
FILE: client/app/priority/high/page.tsx
================================================
import PriorityPage from "@/components/priorityPage";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return <PriorityPage priority={Priority.High} />;
}

export default Page;


================================================
FILE: client/app/priority/low/page.tsx
================================================
import PriorityPage from "@/components/priorityPage";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return <PriorityPage priority={Priority.Low} />;
}

export default Page;


================================================
FILE: client/app/priority/medium/page.tsx
================================================
import PriorityPage from "@/components/priorityPage";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return <PriorityPage priority={Priority.Medium} />;
}

export default Page;


================================================
FILE: client/app/priority/urgent/page.tsx
================================================
import PriorityPage from "@/components/priorityPage";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return <PriorityPage priority={Priority.Urgent} />;
}

export default Page;


================================================
FILE: client/app/projects/[id]/page.tsx
================================================
import ProjectPage from "@/components/project-page";

type Props = {
  params: {
    id: string;
  };
};

function Page({ params }: Props) {
  const { id } = params;

  return <ProjectPage id={id} />;
}

export default Page;


================================================
FILE: client/app/search/page.tsx
================================================
import SearchPage from "@/components/search-page";

type Props = {};

function Page({}: Props) {
  return <SearchPage />;
}

export default Page;


================================================
FILE: client/app/settings/page.tsx
================================================
import SettingsPage from "@/components/settings-page";
import React from "react";

type Props = {};

function Page({}: Props) {
  return <SettingsPage />;
}

export default Page;


================================================
FILE: client/app/teams/page.tsx
================================================
import TeamPage from "@/components/team-page";

type Props = {};

function Page({}: Props) {
  return <TeamPage />;
}

export default Page;


================================================
FILE: client/app/timeline/page.tsx
================================================
import TimeLinePage from "@/components/timeline";
import React from "react";

type Props = {};

function Page({}: Props) {
  return <TimeLinePage />;
}

export default Page;


================================================
FILE: client/app/users/page.tsx
================================================
import UserPage from "@/components/user-page";

type Props = {};

function Page({}: Props) {
  return <UserPage />;
}

export default Page;


================================================
FILE: client/components/Header/index.tsx
================================================
import React from "react";

type Props = {
  name: string;
  buttonComponent?: any;
  isSmallText?: boolean;
};

function Header({ name, buttonComponent, isSmallText }: Props) {
  return (
    <div className="mb-5 flex w-full items-center justify-between">
      <h1
        className={`${isSmallText ? "text-lg" : "text-2xl"} font-semibold dark:text-white`}
      >
        {name}
      </h1>
      {buttonComponent}
    </div>
  );
}

export default Header;


================================================
FILE: client/components/data/columns.tsx
================================================
import {
  GridColDef,
  GridToolbarContainer,
  GridToolbarExport,
  GridToolbarFilterButton,
} from "@mui/x-data-grid";

export const columns: GridColDef[] = [
  {
    field: "title",
    headerName: "Title",
    width: 100,
  },
  {
    field: "description",
    headerName: "Description",
    width: 200,
  },
  {
    field: "status",
    headerName: "Status",
    width: 130,
    renderCell: (params) => (
      <span className="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800">
        {params.value}
      </span>
    ),
  },
  {
    field: "priority",
    headerName: "Priority",
    width: 75,
  },
  {
    field: "tags",
    headerName: "Tags",
    width: 130,
  },
  {
    field: "startDate",
    headerName: "Start Date",
    width: 130,
  },
  {
    field: "dueDate",
    headerName: "Due Date",
    width: 130,
  },
  {
    field: "author",
    headerName: "Author",
    width: 150,
    renderCell: (params) => params.value?.author || "Unknown",
  },
  {
    field: "assignee",
    headerName: "Assignee",
    width: 150,
    renderCell: (params) => params.value?.assignee || "Unassigned",
  },
];

export const userSettings = {
  username: "johndoe",
  email: "john.doe@example.com",
  teamName: "Development Team",
  roleName: "Developer",
};

export const CustomToolbar = () => (
  <GridToolbarContainer className="toolbar flex gap-2">
    <GridToolbarFilterButton />
    <GridToolbarExport />
  </GridToolbarContainer>
);

export const taskColumns: GridColDef[] = [
  { field: "title", headerName: "Title", width: 200 },
  { field: "status", headerName: "Status", width: 150 },
  { field: "priority", headerName: "Priority", width: 150 },
  { field: "dueDate", headerName: "Due Date", width: 150 },
];

export const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];

export const priorityColumns: GridColDef[] = [
  {
    field: "title",
    headerName: "Title",
    width: 100,
  },
  {
    field: "description",
    headerName: "Description",
    width: 200,
  },
  {
    field: "status",
    headerName: "Status",
    width: 130,
    renderCell: (params) => (
      <span className="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800">
        {params.value}
      </span>
    ),
  },
  {
    field: "priority",
    headerName: "Priority",
    width: 75,
  },
  {
    field: "tags",
    headerName: "Tags",
    width: 130,
  },
  {
    field: "startDate",
    headerName: "Start Date",
    width: 130,
  },
  {
    field: "dueDate",
    headerName: "Due Date",
    width: 130,
  },
  {
    field: "author",
    headerName: "Author",
    width: 150,
    renderCell: (params) => params.value?.username || "Unknown",
  },
  {
    field: "assignee",
    headerName: "Assignee",
    width: 150,
    renderCell: (params) => params.value?.username || "Unassigned",
  },
];

export const formFields = {
  signUp: {
    username: {
      order: 1,
      placeholder: "Choose a username",
      label: "Username",
      inputProps: { required: true },
    },
    email: {
      order: 1,
      placeholder: "Enter your email address",
      label: "Email",
      inputProps: { type: "email", required: true },
    },
    password: {
      order: 3,
      placeholder: "Enter your password",
      label: "Password",
      inputProps: { type: "password", required: true },
    },
    confirm_password: {
      order: 4,
      placeholder: "Confirm your password",
      label: "Confirm Password",
      inputProps: { type: "password", required: true },
    },
  },
};


================================================
FILE: client/components/global/auth-provider/index.tsx
================================================
import { formFields } from "@/components/data/columns";
import { Authenticator } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
import { Amplify } from "aws-amplify";
import React from "react";

type Props = {
  children: React.ReactNode;
};

Amplify.configure({
  Auth: {
    Cognito: {
      userPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID!,
      userPoolClientId: process.env.NEXT_PUBLIC_COGNITO_USER_CLIENT_ID!,
    },
  },
});

function AuthProvider({ children }: Props) {
  return (
    <div>
      <Authenticator formFields={formFields}>
        {({ user }: any) =>
          user ? (
            <div>{children}</div>
          ) : (
            <div>
              <h1>Please Sign In Below</h1>
            </div>
          )
        }
      </Authenticator>
    </div>
  );
}

export default AuthProvider;


================================================
FILE: client/components/global/border-view/index.tsx
================================================
import { useGetTasksQuery, useUpdateTasksMutation } from "@/state/api";
import React from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { Spinner } from "../loader/spinner";
import TaskColumn from "../task-column";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

const taskStatus = ["To Do", "Work In Progress", "Under Review", "Completed"];

function BorderView({ id, setIsModelNewTasOpen }: Props) {
  const {
    data: tasks,
    isLoading,
    error,
  } = useGetTasksQuery({ projectId: Number(id) });

  const [updateTaskStatus] = useUpdateTasksMutation();

  const moveTask = (taskId: number, toStatus: string) => {
    updateTaskStatus({ taskId, status: toStatus });
  };

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <DndProvider backend={HTML5Backend}>
      <div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2 xl:grid-cols-4">
        {taskStatus.map((status) => (
          <TaskColumn
            key={status}
            status={status}
            tasks={tasks || []}
            moveTask={moveTask}
            setIsModelNewTasOpen={setIsModelNewTasOpen}
          />
        ))}
      </div>
    </DndProvider>
  );
}

export default BorderView;


================================================
FILE: client/components/global/loader/spinner.tsx
================================================
type SpinnerProps = {
  color?: string;
};

export const Spinner = ({ color }: SpinnerProps) => {
  return (
    <div
      role="status"
      className="flex h-full w-full items-center justify-center"
    >
      <svg
        aria-hidden="true"
        className="inline h-8 w-8 animate-spin fill-yellow-400 text-gray-200 dark:text-gray-600"
        viewBox="0 0 100 101"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
          fill={color || "#fff"}
        />
        <path
          d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
          fill={color || "#fff"}
        />
      </svg>
    </div>
  );
};


================================================
FILE: client/components/global/project-header/index.tsx
================================================
import TabButton from "@/components/global/tab-button";
import Header from "@/components/Header";
import ModalNewProject from "@/components/modal/modal-new-project";
import {
  Clock,
  Filter,
  Grid3x3,
  Grid3X3,
  List,
  PlusSquare,
  Share2,
  Table,
} from "lucide-react";
import { useState } from "react";

type Props = {
  activeTab: string;
  setActiveTab: (tabName: string) => void;
};

function ProjectHeader({ activeTab, setActiveTab }: Props) {
  const [isModalNameProjectOpen, setIsModalNameProjectOpen] = useState(false);

  return (
    <div className="px-4 xl:px-6">
      <ModalNewProject
        isOpen={isModalNameProjectOpen}
        onClose={() => setIsModalNameProjectOpen(false)}
      />
      <div className="pb-6 pt-6 lg:pb-4 lg:pt-8">
        <Header
          name="Product Design Development"
          buttonComponent={
            <button
              className="flex items-center rounded-md bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
              onClick={() => setIsModalNameProjectOpen(true)}
            >
              <PlusSquare className="mr-2 h-5 w-5" /> New Board
            </button>
          }
        />
      </div>
      <div className="flex flex-wrap-reverse gap-2 border-y border-gray-200 pb-[8px] pt-2 dark:border-stroke-dark md:items-center">
        <div className="flex flex-1 items-center gap-2 md:gap-4">
          <TabButton
            name="Board"
            icon={<Grid3X3 className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="List"
            icon={<List className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="Timeline"
            icon={<Clock className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="Table"
            icon={<Table className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
        </div>
        <div className="flex items-center gap-2">
          <button className="text-gray-500 hover:text-gray-600 dark:text-neutral-500 dark:hover:text-gray-300">
            <Filter className="h-5 w-5" />
          </button>
          <button className="text-gray-500 hover:text-gray-600 dark:text-neutral-500 dark:hover:text-gray-300">
            <Share2 className="h-5 w-5" />
          </button>
          <div className="relative">
            <input
              type="text"
              placeholder="Search Task"
              className="rounded-md border py-1 pl-10 pr-4 focus:outline-none dark:border-dark-secondary dark:bg-dark-secondary dark:text-white"
            />
            <Grid3x3 className="absolute left-3 top-2 h-4 w-4 text-gray-400 dark:text-neutral-500" />
          </div>
        </div>
      </div>
    </div>
  );
}

export default ProjectHeader;


================================================
FILE: client/components/global/tab-button/index.tsx
================================================
import React from "react";

type Props = {
  name: string;
  icon: React.ReactNode;
  setActiveTab: (tabName: string) => void;
  activeTab: string;
};

function TabButton({ activeTab, icon, name, setActiveTab }: Props) {
  const isActive = activeTab === name;

  return (
    <button
      className={`relative flex items-center gap-2 px-1 py-2 text-gray-500 after:absolute after:-bottom-[9px] after:left-0 after:h-[1px] after:w-full hover:text-blue-600 dark:text-neutral-500 dark:hover:text-white sm:px-2 lg:px-4 ${
        isActive ? "text-blue-600 after:bg-blue-600 dark:text-white" : ""
      }`}
      onClick={() => setActiveTab(name)}
    >
      {icon}
      {name}
    </button>
  );
}

export default TabButton;


================================================
FILE: client/components/global/task/index.tsx
================================================
import { TasksTypes } from "@/types/type";
import { format } from "date-fns";
import { EllipsisVertical, MessageSquareMore } from "lucide-react";
import Image from "next/image";
import { useDrag } from "react-dnd";

type Props = {
  task: TasksTypes;
};

function Task({ task }: Props) {
  const [{ isDragging }, drop] = useDrag(() => ({
    type: "task",
    item: { id: task.id },
    collect: (monitor: any) => ({
      isDragging: !!monitor.isDragging(),
    }),
  }));

  const taskTagsSplit = task.tags ? task.tags.split(",") : [];

  const formattedStartDate = task.startDate
    ? format(new Date(task.startDate), "P")
    : "";

  const formattedDueDate = task.dueDate
    ? format(new Date(task.dueDate), "P")
    : "";

  const numberOfComments = (task.comments && task.comments.length) || 0;

  const PriorityTags = ({ priority }: { priority: TasksTypes["priority"] }) => (
    <div
      className={`rounded-full px-2 py-1 text-xs font-semibold ${
        priority === "Urgent"
          ? "bg-red-200 text-red-700"
          : priority === "High"
            ? "bg-yellow-200 text-yellow-700"
            : priority === "Medium"
              ? "bg-green-200 text-green-700"
              : priority === "Low"
                ? "bg-blue-200 text-blue-700"
                : "bg-gray-200 text-gray-700"
      }`}
    >
      {priority}
    </div>
  );

  return (
    <div
      ref={(instance) => {
        drop(instance);
      }}
      className={`mb-4 rounded-md bg-white shadow dark:bg-dark-secondary ${
        isDragging ? "opacity-50" : "opacity-100"
      }`}
    >
      {task.attachments && task.attachments.length > 0 && (
        <Image
          src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${task.attachments[0].fileURL}`}
          alt={task.attachments[0].fileName}
          width={400}
          height={200}
          className="h-auto w-full rounded-md"
        />
      )}
      <div className="p-4 md:p-6">
        <div className="flex items-start justify-between">
          <div className="flex flex-1 flex-wrap items-center gap-2">
            {task.priority && <PriorityTags priority={task.priority} />}

            <div className="flex gap-2">
              {taskTagsSplit.map((tag) => (
                <div
                  key={tag}
                  className="rounded-full bg-blue-100 px-2 py-1 text-xs"
                >
                  {" "}
                  {tag}
                </div>
              ))}
            </div>
          </div>
          <button className="flex h-6 w-4 flex-shrink-0 items-center justify-center dark:text-neutral-500">
            <EllipsisVertical size={26} />
          </button>
        </div>
        <div className="my-3 flex justify-between">
          <h4 className="text-md font-bold dark:text-white">{task.title}</h4>
          {typeof task.points === "number" && (
            <div className="text-xs font-semibold dark:text-white">
              {task.points} pts
            </div>
          )}
        </div>
        <div className="text-xs text-gray-500 dark:text-neutral-500">
          {formattedStartDate && <span>{formattedStartDate} - </span>}
          {formattedDueDate && <span>{formattedDueDate}</span>}
        </div>
        <p className="text-sm font-semibold text-gray-600 dark:text-neutral-500">
          {task.description}
        </p>
        <div className="mt-4 border-t border-gray-200 dark:border-stroke-dark" />

        <div className="mt-3 flex items-center justify-between">
          <div className="flex -space-x-[6px] overflow-hidden">
            {task.assignee && (
              <Image
                src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${task.assignee.profilePictureUrl}`}
                alt={task.assignee.username}
                width={30}
                height={30}
                className="h-8 w-8 rounded-full border-2 border-white object-cover dark:border-dark-secondary"
              />
            )}
            {task.author && (
              <Image
                src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${task.author.profilePictureUrl}`}
                alt={task.author.username}
                width={30}
                height={30}
                className="h-8 w-8 rounded-full border-2 border-white object-cover dark:border-dark-secondary"
              />
            )}
          </div>
          <div className="flex items-center text-gray-500 dark:text-neutral-500">
            <MessageSquareMore size={20} />
            <span className="ml-1 text-sm dark:text-neutral-400">
              {numberOfComments}
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

export default Task;


================================================
FILE: client/components/global/task-card/index.tsx
================================================
import { TasksTypes } from "@/types/type";
import { format } from "date-fns";
import Image from "next/image";
import React from "react";

type Props = {
  task: TasksTypes;
};

function TaskCard({ task }: Props) {
  return (
    <div className="mb-3 rounded bg-white p-4 shadow dark:bg-dark-secondary dark:text-white">
      {task.attachments && task.attachments.length > 0 && (
        <div>
          <strong>Attachments:</strong>
          <div className="flex flex-wrap">
            {task.attachments && task.attachments.length > 0 && (
              <Image
                src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${task.attachments[0].fileURL}`}
                alt={task.attachments[0].fileName}
                width={400}
                height={200}
                className="rounded-md"
              />
            )}
          </div>
        </div>
      )}
      <p>
        <strong>ID:</strong> {task.id}
      </p>
      <p>
        <strong>Title:</strong> {task.title}
      </p>
      <p>
        <strong>Description:</strong>{" "}
        {task.description || "No description provided"}
      </p>
      <p>
        <strong>Status:</strong> {task.status}
      </p>
      <p>
        <strong>Priority:</strong> {task.priority}
      </p>
      <p>
        <strong>Tags:</strong> {task.tags || "No tags"}
      </p>
      <p>
        <strong>Start Date:</strong>{" "}
        {task.startDate ? format(new Date(task.startDate), "P") : "Not set"}
      </p>
      <p>
        <strong>Due Date:</strong>{" "}
        {task.dueDate ? format(new Date(task.dueDate), "P") : "Not set"}
      </p>
      <p>
        <strong>Author:</strong>{" "}
        {task.author ? task.author.username : "Unknown"}
      </p>
      <p>
        <strong>Assignee:</strong>{" "}
        {task.assignee ? task.assignee.username : "Unassigned"}
      </p>
    </div>
  );
}

export default TaskCard;


================================================
FILE: client/components/global/task-column/index.tsx
================================================
import { EllipsisVertical, Plus } from "lucide-react";
import React from "react";
import { useDrop } from "react-dnd";
import Task from "../task";
import { TasksTypes } from "@/types/type";

type Props = {
  status: string;
  tasks: TasksTypes[];
  moveTask: (taskId: number, toStatus: string) => void;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function TaskColumn({ moveTask, setIsModelNewTasOpen, status, tasks }: Props) {
  const [{ isOver }, drop] = useDrop(() => ({
    accept: "task",
    drop: (item: { id: number }) => moveTask(item.id, status),
    collect: (monitor: any) => ({
      isOver: !!monitor.isOver(),
    }),
  }));

  const tasksCount = tasks.filter((task) => task.status === status).length;

  const statusColor: any = {
    "To Do": "#2563EB",
    "Work In Progress": "#059669",
    "Under Review": "#D97706",
    Completed: "#000000",
  };

  return (
    <div
      ref={(instance) => {
        drop(instance);
      }}
      className={`sl:py-4 rounded-lg py-2 xl:px-2 ${isOver ? "bg-blue-100 dark:bg-neutral-950" : ""}`}
    >
      <div className="mb-3 flex w-full">
        <div
          className={`w-2 !bg-[${statusColor[status]}] rounded-s-lg`}
          style={{ backgroundColor: statusColor[status] }}
        />
        <div className="flex w-full items-center justify-between rounded-e-lg bg-white px-5 py-4 dark:bg-dark-secondary">
          <h3 className="flex items-center text-lg font-semibold dark:text-white">
            {status}{" "}
            <span
              className="ml-2 inline-block rounded-full bg-gray-200 p-1 text-center text-sm leading-none dark:bg-dark-tertiary"
              style={{ width: "1.5rem", height: "1.5rem" }}
            >
              {tasksCount}
            </span>
          </h3>
          <div className="flex items-center gap-1">
            <button className="flex h-6 w-5 items-center justify-center dark:text-neutral-500">
              <EllipsisVertical size={26} />
            </button>
            <button
              className="flex h-6 w-6 items-center justify-center rounded bg-gray-200 dark:bg-dark-tertiary dark:text-white"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              <Plus size={16} />
            </button>
          </div>
        </div>
      </div>

      {tasks
        .filter((task) => task.status === status)
        .map((task) => (
          <Task key={task.id} task={task} />
        ))}
    </div>
  );
}
export default TaskColumn;


================================================
FILE: client/components/home-page/index.tsx
================================================
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetProjectsQuery, useGetTasksQuery } from "@/state/api";
import { Priority, ProjectTypes, TasksTypes } from "@/types/type";
import { DataGrid } from "@mui/x-data-grid";
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { COLORS, taskColumns } from "../data/columns";
import { Spinner } from "../global/loader/spinner";
import Header from "../Header";
import { useAppSelector } from "../wrapper/redux";

type Props = {};

function HomePage({}: Props) {
  const {
    data: tasks,
    isLoading: tasksLoading,
    isError: tasksError,
  } = useGetTasksQuery({
    projectId: parseInt("1"),
  });
  const { data: projects, isLoading: isProjectsLoading } =
    useGetProjectsQuery();

  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  if (tasksLoading || isProjectsLoading) return <Spinner />;
  if (tasksError || !tasks || !projects)
    return <div>An error has occurred</div>;

  const priorityCount = tasks.reduce(
    (acc: Record<string, number>, task: TasksTypes) => {
      const { priority } = task;
      acc[priority as Priority] = (acc[priority as Priority] || 0) + 1;
      return acc;
    },
    {},
  );

  const taskDistribution = Object.keys(priorityCount).map((key) => ({
    name: key,
    count: priorityCount[key],
  }));

  const statusCount = projects.reduce(
    (acc: Record<string, number>, project: ProjectTypes) => {
      const status = project.endDate ? "Completed" : "Active";
      acc[status] = (acc[status] || 0) + 1;
      return acc;
    },
    {},
  );

  const projectStatus = Object.keys(statusCount).map((key) => ({
    name: key,
    count: statusCount[key],
  }));

  const chartColors = isDarkMode
    ? {
        bar: "#8884d8",
        barGrid: "#303030",
        pieFill: "#4A90E2",
        text: "#FFFFFF",
      }
    : {
        bar: "#8884d8",
        barGrid: "#E0E0E0",
        pieFill: "#82ca9d",
        text: "#000000",
      };

  return (
    <div className="container h-full w-[100%] bg-gray-100 bg-transparent p-8">
      <Header name="Project Management Dashboard" />
      <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
        <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary">
          <h3 className="mb-4 text-lg font-semibold dark:text-white">
            Task Priority Distribution
          </h3>
          <ResponsiveContainer width="100%" height={300}>
            <BarChart data={taskDistribution}>
              <CartesianGrid
                strokeDasharray="3 3"
                stroke={chartColors.barGrid}
              />
              <XAxis dataKey="name" stroke={chartColors.text} />
              <YAxis stroke={chartColors.text} />
              <Tooltip
                contentStyle={{
                  width: "min-content",
                  height: "min-content",
                }}
              />
              <Legend />
              <Bar dataKey="count" fill={chartColors.bar} />
            </BarChart>
          </ResponsiveContainer>
        </div>
        <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary">
          <h3 className="mb-4 text-lg font-semibold dark:text-white">
            Project Status
          </h3>
          <ResponsiveContainer width="100%" height={300}>
            <PieChart>
              <Pie dataKey="count" data={projectStatus} fill="#82ca9d" label>
                {projectStatus.map((entry, index) => (
                  <Cell
                    key={`cell-${index}`}
                    fill={COLORS[index % COLORS.length]}
                  />
                ))}
              </Pie>
              <Tooltip />
              <Legend />
            </PieChart>
          </ResponsiveContainer>
        </div>
        <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary md:col-span-2">
          <h3 className="mb-4 text-lg font-semibold dark:text-white">
            Your Tasks
          </h3>
          <div style={{ height: 400, width: "100%" }}>
            <DataGrid
              rows={tasks}
              columns={taskColumns}
              checkboxSelection
              loading={tasksLoading}
              getRowClassName={() => "data-grid-row"}
              getCellClassName={() => "data-grid-cell"}
              className={dataGridClassNames}
              sx={dataGridSxStyles(isDarkMode)}
            />
          </div>
        </div>
      </div>
    </div>
  );
}
export default HomePage;


================================================
FILE: client/components/list-view/index.tsx
================================================
import { useGetTasksQuery } from "@/state/api";
import { TasksTypes } from "@/types/type";
import { Spinner } from "../global/loader/spinner";
import TaskCard from "../global/task-card";
import Header from "../Header";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function ListView({ id, setIsModelNewTasOpen }: Props) {
  const {
    data: tasks,
    error,
    isLoading,
  } = useGetTasksQuery({ projectId: Number(id) });

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="px-4 pb-8 xl:px-6">
      <div className="pt-5">
        <Header
          name="List"
          buttonComponent={
            <button
              className="hove:bg-blue-600 flex items-center rounded-md bg-blue-primary px-3 py-3 text-white"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              Add Task
            </button>
          }
          isSmallText
        />
      </div>
      <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6">
        {tasks?.map((task: TasksTypes) => (
          <TaskCard key={task.id} task={task} />
        ))}
      </div>
    </div>
  );
}

export default ListView;


================================================
FILE: client/components/modal/index.tsx
================================================
import Header from "@/components/Header";
import { X } from "lucide-react";
import React from "react";
import ReactDOM from "react-dom";

type Props = {
  children: React.ReactNode;
  isOpen: boolean;
  onClose: () => void;
  name: string;
};

function Modal({ children, isOpen, onClose, name }: Props) {
  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div className="fixed inset-0 z-50 flex h-full w-full items-center justify-center overflow-y-auto bg-gray-600 bg-opacity-50 p-4">
      <div className="w-full max-w-2xl rounded-lg bg-white p-4 shadow-lg dark:bg-dark-secondary">
        <Header
          name={name}
          buttonComponent={
            <button
              className="flex h-7 w-7 items-center justify-center rounded-full bg-blue-primary text-white hover:bg-blue-600"
              onClick={onClose}
            >
              <X size={18} />
            </button>
          }
          isSmallText
        />
        {children}
      </div>
    </div>,
    document.body,
  );
}

export default Modal;


================================================
FILE: client/components/modal/modal-new-project/index.tsx
================================================
import { Spinner } from "@/components/global/loader/spinner";
import { useCreateProjectMutation } from "@/state/api";
import { formatISO } from "date-fns";
import { useState } from "react";
import Modal from "..";

type Props = {
  isOpen: boolean;
  onClose: () => void;
};

function ModalNewProject({ isOpen, onClose }: Props) {
  const [createProject, { isLoading }] = useCreateProjectMutation();
  const [projectName, setProjectName] = useState("");
  const [description, setDescription] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");

  const handleSubmit = async () => {
    if (!projectName || !startDate || !endDate) return;

    const formateStartDate = formatISO(new Date(startDate), {
      representation: "complete",
    });
    const formateEndDate = formatISO(new Date(endDate), {
      representation: "complete",
    });

    await createProject({
      name: projectName,
      description,
      startDate: formateStartDate,
      endDate: formateEndDate,
    });

    onClose();
  };

  const isFormValid = () => {
    return projectName && description && startDate && endDate;
  };

  const inputStyle =
    "w-full rounded-md border border-gray-300 p-2 shadow-sm dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  return (
    <Modal isOpen={isOpen} onClose={onClose} name="Create New Project">
      <form
        className="mt-4 space-y-6"
        onSubmit={(e) => {
          e.preventDefault();
          handleSubmit();
        }}
      >
        <input
          type="text"
          className={inputStyle}
          placeholder="Project Name"
          value={projectName}
          onChange={(e) => setProjectName(e.target.value)}
        />
        <textarea
          className={inputStyle}
          placeholder="Description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <input
            type="date"
            className={inputStyle}
            value={startDate}
            onChange={(e) => setStartDate(e.target.value)}
          />
          <input
            type="date"
            className={inputStyle}
            value={endDate}
            onChange={(e) => setEndDate(e.target.value)}
          />
        </div>
        <button
          type="submit"
          className={`focus-offset-2 mt-4 flex w-full justify-center rounded-md border border-transparent bg-blue-primary px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-600 ${
            !isFormValid() || isLoading ? "cursor-not-allowed opacity-50" : ""
          }`}
          disabled={!isFormValid() || isLoading}
        >
          {isLoading ? <Spinner /> : "Create Project"}
        </button>
      </form>
    </Modal>
  );
}

export default ModalNewProject;


================================================
FILE: client/components/modal/model-new-task/index.tsx
================================================
import { Spinner } from "@/components/global/loader/spinner";
import { useCreateTasksMutation } from "@/state/api";
import { Priority, Status } from "@/types/type";
import { formatISO } from "date-fns";
import { useState } from "react";
import Modal from "..";

type Props = {
  id?: string | null;
  isOpen: boolean;
  onClose: () => void;
};

function ModelNewTask({ id, isOpen, onClose }: Props) {
  const [createTask, { isLoading }] = useCreateTasksMutation();
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [status, setStatus] = useState<Status>(Status.ToDo);
  const [priority, setPriority] = useState<Priority>(Priority.Backlog);
  const [tags, setTags] = useState("");
  const [startDate, setStartDate] = useState("");
  const [dueDate, setDueDate] = useState("");
  const [authorUserId, setAuthorUserId] = useState("");
  const [assignedUserId, setAssignedUserId] = useState("");
  const [projectId, setProjectId] = useState("");

  console.log(id);

  const handleSubmit = async () => {
    if (!title || !authorUserId || !(id !== null || projectId)) return;

    const formateStartDate = formatISO(new Date(startDate), {
      representation: "complete",
    });
    const formateEndDate = formatISO(new Date(dueDate), {
      representation: "complete",
    });

    await createTask({
      title,
      description,
      status,
      priority,
      tags,
      startDate: formateStartDate,
      dueDate: formateEndDate,
      authorUserId: parseInt(authorUserId),
      assignedUserId: parseInt(assignedUserId),
      projectId: id !== null ? Number(id) : Number(projectId),
    });

    onClose();
  };

  const isFormValid = () => {
    return title && authorUserId && (id !== null || projectId);
  };

  const selectStyles =
    "mb-4 block w-full rounded border border-gray-300 px-3 py-2 dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  const inputStyle =
    "w-full rounded-md border border-gray-300 p-2 shadow-sm dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  return (
    <Modal isOpen={isOpen} onClose={onClose} name="Create New Project">
      <form
        className="mt-4 space-y-6"
        onSubmit={(e) => {
          e.preventDefault();
          handleSubmit();
        }}
      >
        <input
          type="text"
          className={inputStyle}
          placeholder="Title"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <textarea
          className={inputStyle}
          placeholder="Description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <select
            className={selectStyles}
            value={status}
            onChange={(e) =>
              setStatus(Status[e.target.value as keyof typeof Status])
            }
          >
            <option value="">Select Status</option>
            <option value={Status.ToDo}>To Do</option>
            <option value={Status.WorkInProgress}>Work In Progress</option>
            <option value={Status.UnderReview}>Under Review</option>
            <option value={Status.Completed}>Completed</option>
          </select>
          <select
            className={selectStyles}
            value={priority}
            onChange={(e) =>
              setPriority(Priority[e.target.value as keyof typeof Priority])
            }
          >
            <option value="">Select Priority</option>
            <option value={Priority.Urgent}>Urgent</option>
            <option value={Priority.High}>High</option>
            <option value={Priority.Medium}>Medium</option>
            <option value={Priority.Low}>Low</option>
            <option value={Priority.Backlog}>Backlog</option>
          </select>
        </div>
        <input
          type="text"
          className={inputStyle}
          placeholder="Tags (comma separated)"
          value={tags}
          onChange={(e) => setTags(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <input
            type="date"
            className={inputStyle}
            value={startDate}
            onChange={(e) => setStartDate(e.target.value)}
          />
          <input
            type="date"
            className={inputStyle}
            value={dueDate}
            onChange={(e) => setDueDate(e.target.value)}
          />
        </div>
        <input
          type="text"
          className={inputStyle}
          placeholder="Author User ID"
          value={authorUserId}
          onChange={(e) => setAuthorUserId(e.target.value)}
        />
        <input
          type="text"
          className={inputStyle}
          placeholder="Assigned User ID"
          value={assignedUserId}
          onChange={(e) => setAssignedUserId(e.target.value)}
        />
        {id === undefined && (
          <input
            type="text"
            className={inputStyle}
            placeholder="Project Id"
            value={projectId}
            onChange={(e) => setProjectId(e.target.value)}
          />
        )}
        <button
          type="submit"
          className={`focus-offset-2 mt-4 flex w-full justify-center rounded-md border border-transparent bg-blue-primary px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-600 ${
            !isFormValid() || isLoading ? "cursor-not-allowed opacity-50" : ""
          }`}
          disabled={!isFormValid() || isLoading}
        >
          {isLoading ? <Spinner /> : "Create Project"}
        </button>
      </form>
    </Modal>
  );
}

export default ModelNewTask;


================================================
FILE: client/components/navbar/index.tsx
================================================
import { setIsDarkMode, setIsSidebarCollapsed } from "@/state";
import { useGetAuthUserQuery } from "@/state/api";
import { signOut } from "aws-amplify/auth";
import { Menu, Moon, Search, Settings, Sun, User } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import React from "react";
import { useAppDispatch, useAppSelector } from "../wrapper/redux";

type Props = {};

function Navbar({}: Props) {
  const dispatch = useAppDispatch();
  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed,
  );
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  const { data: currentUser } = useGetAuthUserQuery({});

  const handleSignOut = async () => {
    try {
      await signOut();
    } catch (error: any) {
      console.log("🚀 ~ handleSignUp ~ error:", error);
    }
  };

  if (!currentUser) return null;
  const currentUserDetails = currentUser.user;

  return (
    <div className="flex items-center justify-between bg-white px-4 py-3 dark:bg-black">
      <div className="flex items-center gap-8">
        {!isSidebarCollapsed ? null : (
          <button
            onClick={() => dispatch(setIsSidebarCollapsed(!isSidebarCollapsed))}
          >
            <Menu className="h-8 w-8 dark:text-white" />
          </button>
        )}
        <div className="relative flex h-min w-[200px]">
          <Search className="absolute left-[4px] top-1/2 mr-2 h-5 w-5 -translate-y-1/2 transform cursor-pointer dark:text-white" />
          <input
            className="w-full rounded border-none bg-gray-100 p-2 pl-8 placeholder-gray-500 focus:border-transparent focus:outline-none dark:bg-gray-700 dark:text-white dark:placeholder-white"
            type="search"
            placeholder="Search..."
          />
        </div>
      </div>
      <div className="flex items-center">
        <button
          onClick={() => dispatch(setIsDarkMode(!isDarkMode))}
          className={
            isDarkMode
              ? `rounded p-2 dark:hover:bg-gray-700`
              : `rounded p-2 hover:bg-gray-100`
          }
        >
          {isDarkMode ? (
            <Sun className="h-6 w-6 cursor-pointer dark:text-white" />
          ) : (
            <Moon className="h-6 w-6 cursor-pointer dark:text-white" />
          )}
        </button>
        <Link
          href="/settings"
          className={
            isDarkMode
              ? `h-min w-min rounded p-2 dark:hover:bg-gray-700`
              : `h-min w-min rounded p-2 hover:bg-gray-100`
          }
        >
          <Settings className="h-6 w-6 cursor-pointer dark:text-white" />
        </Link>
        <div className="ml-2 mr-5 hidden min-h-[2em] w-[0.1rem] bg-gray-200 md:inline-block"></div>
        <div className="hidden items-center justify-between md:flex">
          <div className="align-center flex h-9 w-9 justify-center">
            <User className="h-6 w-6 cursor-pointer self-center rounded-full dark:text-white" />
          </div>
          <span className="mx-3 text-gray-800 dark:text-white">
            {currentUserDetails?.username}
          </span>
          <button
            className="hidden rounded bg-blue-400 px-4 py-2 text-xs font-bold text-white hover:bg-blue-500 md:block"
            onClick={handleSignOut}
          >
            Sign out
          </button>
        </div>
      </div>
    </div>
  );
}

export default Navbar;


================================================
FILE: client/components/priorityPage/index.tsx
================================================
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetAuthUserQuery, useGetTasksByUserQuery } from "@/state/api";
import { Priority, TasksTypes } from "@/types/type";
import { DataGrid } from "@mui/x-data-grid";
import { useState } from "react";
import { priorityColumns } from "../data/columns";
import TaskCard from "../global/task-card";
import Header from "../Header";
import ModelNewTask from "../modal/model-new-task";
import { useAppSelector } from "../wrapper/redux";

type Props = {
  priority: Priority;
};

function PriorityPage({ priority }: Props) {
  const [view, setView] = useState("list");
  const [isMobileNewTaskOpen, setIsMobileNewTaskOpen] = useState(false);
  const { data: currentUser } = useGetAuthUserQuery({});

  const userId = Number(currentUser?.user?.userId) ?? null;

  const {
    data: task,
    isLoading,
    isError: isTasksError,
  } = useGetTasksByUserQuery(userId || 0, { skip: userId == null });

  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
  const filteredTasks = task?.filter(
    (t: TasksTypes) => t.priority === priority,
  );

  if (isTasksError || !task) return <div>An error occurred</div>;

  return (
    <div className="m-5 p-4">
      <ModelNewTask
        isOpen={isMobileNewTaskOpen}
        onClose={() => setIsMobileNewTaskOpen(false)}
      />
      <Header
        name="Priority Page"
        buttonComponent={
          <button
            className="mr-3 rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700"
            onClick={() => setIsMobileNewTaskOpen(true)}
          >
            Add Task
          </button>
        }
      />
      <div className="mb-4 flex justify-start">
        <button
          className={`rounded-bl-md rounded-tl-md px-4 py-2 ${
            view === "list" ? "bg-gray-300" : "bg-white"
          } `}
          onClick={() => setView("list")}
        >
          List
        </button>
        <button
          className={`rounded-br-md rounded-tr-md px-4 py-2 ${
            view === "table" ? "bg-gray-300" : "bg-white"
          } `}
          onClick={() => setView("table")}
        >
          Table
        </button>
      </div>
      {isLoading ? (
        <div>Loading tasks...</div>
      ) : view === "list" ? (
        <div className="grid grid-cols-1 gap-4">
          {filteredTasks?.map((task: TasksTypes) => (
            <TaskCard key={task.id} task={task} />
          ))}
        </div>
      ) : (
        view === "table" &&
        filteredTasks && (
          <div className="z-0 w-full">
            <DataGrid
              rows={filteredTasks}
              columns={priorityColumns}
              checkboxSelection
              getRowId={(row) => row.id}
              className={dataGridClassNames}
              sx={dataGridSxStyles(isDarkMode)}
            />
          </div>
        )
      )}
    </div>
  );
}

export default PriorityPage;


================================================
FILE: client/components/project-card/index.tsx
================================================
import { ProjectTypes } from "@/types/type";
import React from "react";

type Props = {
  project: ProjectTypes;
};

function ProjectCard({ project }: Props) {
  return (
    <div className="rounded border p-4 shadow dark:text-white">
      <h3>{project.name}</h3>
      <p>{project.description}</p>
      <p>Start Date: {project.startDate}</p>
      <p>End Date: {project.endDate}</p>
    </div>
  );
}

export default ProjectCard;


================================================
FILE: client/components/project-page/index.tsx
================================================
"use client";

import { useState } from "react";
import BorderView from "../global/border-view";
import ProjectHeader from "../global/project-header";
import ListView from "../list-view";
import ModelNewTask from "../modal/model-new-task";
import TableView from "../table-view";
import Timeline from "../timeline-view";

type Props = {
  id: string;
};

function ProjectPage({ id }: Props) {
  const [activeTAB, setActiveTAB] = useState("Board");
  const [isModelNewTasOpen, setIsModelNewTasOpen] = useState(false);

  return (
    <div>
      <ModelNewTask
        id={id}
        isOpen={isModelNewTasOpen}
        onClose={() => setIsModelNewTasOpen(false)}
      />
      <ProjectHeader activeTab={activeTAB} setActiveTab={setActiveTAB} />
      {activeTAB === "Board" && (
        <BorderView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
      )}
      {activeTAB === "List" && (
        <ListView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
      )}
      {activeTAB === "Timeline" && (
        <Timeline id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
      )}
      {activeTAB === "Table" && (
        <TableView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
      )}
    </div>
  );
}

export default ProjectPage;


================================================
FILE: client/components/search-page/index.tsx
================================================
"use client";

import { useSearchQuery } from "@/state/api";
import { debounce } from "lodash";
import { useEffect, useState } from "react";
import Header from "../Header";
import { Spinner } from "../global/loader/spinner";
import TaskCard from "../global/task-card";
import ProjectCard from "../project-card";
import UserCard from "../user-card";

type Props = {};

function SearchPage({}: Props) {
  const [searchTerm, setSearchTerm] = useState("");
  const {
    data: searchResults,
    isLoading,
    isError,
  } = useSearchQuery(searchTerm, {
    skip: searchTerm.length < 3,
  });

  const handleSearch = debounce((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(e.target.value);
  }, 500);

  useEffect(() => {
    return handleSearch.cancel;
  }, [handleSearch.cancel]);

  return (
    <div className="p-8">
      <Header name="Search" />
      <div>
        <input
          type="text"
          placeholder="Search..."
          className="w-1/2 rounded border p-3 shadow"
          onChange={handleSearch}
        />
      </div>
      <div className="p-5">
        {isLoading && <Spinner />}
        {isError && <p>Error occurred while fetching search results.</p>}
        {!isLoading && !isError && searchResults && (
          <div>
            {searchResults.tasks && searchResults.tasks?.length > 0 && (
              <h2>Tasks</h2>
            )}
            {searchResults.tasks?.map((task) => (
              <TaskCard key={task.id} task={task} />
            ))}

            {searchResults.projects && searchResults.projects?.length > 0 && (
              <h2>Projects</h2>
            )}
            {searchResults.projects?.map((project) => (
              <ProjectCard key={project.id} project={project} />
            ))}

            {searchResults.users && searchResults.users?.length > 0 && (
              <h2>Users</h2>
            )}
            {searchResults.users?.map((user) => (
              <UserCard key={user.userId} user={user} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

export default SearchPage;


================================================
FILE: client/components/settings-page/index.tsx
================================================
import Header from "../Header";
import { userSettings } from "../data/columns";

type Props = {};

const labelStyles = "block text-sm font-medium dark:text-white";
const textStyles =
  "mt-1 block w-full border border-gray-300 rounded-md shadow-sm p-2 dark:text-white";

function SettingsPage({}: Props) {
  return (
    <div className="p-8">
      <Header name="Settings" />
      <div className="space-y-4">
        <div>
          <label className={labelStyles}>Username</label>
          <div className={textStyles}>{userSettings.username}</div>
        </div>
        <div>
          <label className={labelStyles}>Email</label>
          <div className={textStyles}>{userSettings.email}</div>
        </div>
        <div>
          <label className={labelStyles}>Team</label>
          <div className={textStyles}>{userSettings.teamName}</div>
        </div>
        <div>
          <label className={labelStyles}>Role</label>
          <div className={textStyles}>{userSettings.roleName}</div>
        </div>
      </div>
    </div>
  );
}

export default SettingsPage;


================================================
FILE: client/components/sidebar/index.tsx
================================================
"use client";

import { setIsSidebarCollapsed } from "@/state";
import { useGetAuthUserQuery, useGetProjectsQuery } from "@/state/api";
import { signOut } from "aws-amplify/auth";
import {
  AlertCircle,
  AlertOctagon,
  AlertTriangle,
  Briefcase,
  ChevronDown,
  ChevronUp,
  Home,
  Layers3,
  LockIcon,
  LucideIcon,
  Search,
  Settings,
  ShieldAlert,
  User,
  Users,
  X,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { useDispatch } from "react-redux";
import { useAppSelector } from "../wrapper/redux";

type Props = {};

function SideBar({}: Props) {
  const dispatch = useDispatch();
  const [showProject, setShowProject] = useState(true);
  const [showPriority, setShowPriority] = useState(true);

  const { data: projects } = useGetProjectsQuery();

  const { data: currentUser } = useGetAuthUserQuery({});

  const handleSignOut = async () => {
    try {
      await signOut();
    } catch (error: any) {
      console.log("🚀 ~ handleSignUp ~ error:", error);
    }
  };

  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed,
  );

  if (!currentUser) return null;
  const currentUserDetails = currentUser.user;

  const sideBarClassNames = `fixed flex flex-col h-[100%] justify-between shadow-xl
    transition-all duration-300 h-full z-40 dark:bg-black overflow-y-auto bg-white ${isSidebarCollapsed ? "w-0 hidden" : "w-64"}`;

  return (
    <div className={sideBarClassNames}>
      <div className="flex h-[100%] w-full flex-col justify-start">
        {/*    */}
        <div className="z-50 flex min-h-[56px] w-64 items-center justify-between bg-white px-6 pt-3 dark:bg-black">
          <div className="text-xl font-bold text-gray-800 dark:text-white">
            LIST
          </div>
          {isSidebarCollapsed ? null : (
            <button
              className="py-3"
              onClick={() =>
                dispatch(setIsSidebarCollapsed(!isSidebarCollapsed))
              }
            >
              <X className="h-6 w-6 text-gray-800 hover:text-gray-500 dark:text-white" />
            </button>
          )}
        </div>
        <div className="flex items-center gap-5 border-y-[1.5px] border-gray-500 px-8 py-4 dark:border-gray-700">
          <Image src="/logo.png" alt="logo" width={40} height={40} />
          <div>
            <h3 className="text-lg font-bold tracking-wide dark:text-gray-200">
              TRELLO
            </h3>

            <div className="mt-1 flex items-start gap-2">
              <LockIcon className="mt-[0.1rem] h-3 w-3 text-gray-500 dark:text-gray-400" />
              <p className="text-xs text-gray-500">Private</p>
            </div>
          </div>
        </div>
        <nav className="z-10 w-full">
          <SidebarLink icon={Home} label="Home" href="/" />
          <SidebarLink icon={Briefcase} label="Timeline" href="/timeline" />
          <SidebarLink icon={Search} label="Search" href="/search" />
          <SidebarLink icon={Settings} label="Settings" href="/settings" />
          <SidebarLink icon={User} label="Users" href="/users" />
          <SidebarLink icon={Users} label="Teams" href="/teams" />
        </nav>
        <button
          onClick={() => setShowProject((prev) => !prev)}
          className="flex w-full items-center justify-between px-8 py-3 text-gray-500"
        >
          <span>Projects</span>
          {showProject ? (
            <ChevronUp className="h-5 w-5" />
          ) : (
            <ChevronDown className="h-5 w-5" />
          )}
        </button>
        {showProject &&
          projects?.map((project) => (
            <SidebarLink
              key={project.id}
              icon={Briefcase}
              label={project.name}
              href={`/projects/${project.id}`}
            />
          ))}
        <button
          onClick={() => setShowPriority((prev) => !prev)}
          className="flex w-full items-center justify-between px-8 py-3 text-gray-500"
        >
          <span>Priory</span>
          {showPriority ? (
            <ChevronUp className="h-5 w-5" />
          ) : (
            <ChevronDown className="h-5 w-5" />
          )}
        </button>
        {showPriority && (
          <>
            <SidebarLink
              icon={AlertCircle}
              label="Urgent"
              href="/priority/urgent"
            />
            <SidebarLink
              icon={ShieldAlert}
              label="High"
              href="/priority/high"
            />
            <SidebarLink
              icon={AlertTriangle}
              label="Medium"
              href="/priority/medium"
            />
            <SidebarLink icon={AlertOctagon} label="Low" href="/priority/low" />
            <SidebarLink
              icon={Layers3}
              label="Backlog"
              href="/priority/backlog"
            />
          </>
        )}
      </div>
      <div className="z-10 mt-32 flex w-full flex-col items-center gap-4 bg-white px-8 py-8 dark:bg-black md:hidden">
        <div className="flex w-full items-center">
          <div className="align-center flex h-9 w-9 justify-center">
            <User className="h-6 w-6 cursor-pointer self-center rounded-full dark:text-white" />
          </div>
          <span className="mx-3 text-gray-800 dark:text-white">
            {currentUserDetails?.username}
          </span>
          <button
            className="self-start rounded bg-blue-400 px-4 py-2 text-xs font-bold text-white hover:bg-blue-500 md:block"
            onClick={handleSignOut}
          >
            Sign out
          </button>
        </div>
      </div>
    </div>
  );
}

interface SideBarLinksType {
  href: string;
  icon: LucideIcon;
  label: string;
}

const SidebarLink = ({ href, icon: Icon, label }: SideBarLinksType) => {
  const pathName = usePathname();
  const isActive =
    pathName === href || (pathName === "/" && href === "/dashboard");
  const screenWidth = window.innerWidth;

  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed,
  );
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  return (
    <Link href={href} className="w-full">
      <div
        className={`relative flex cursor-pointer items-center gap-3 rounded-sm transition-colors hover:bg-gray-100 dark:bg-black dark:hover:bg-gray-700 ${isActive ? "bg-gray-100 text-white dark:bg-gray-600" : ""} justify-start px-8 py-3`}
      >
        {isActive && (
          <div className="absolute left-0 top-0 h-[100%] w-[5px] bg-blue-200" />
        )}

        <Icon className="h-6 w-6 text-gray-800 dark:text-gray-500" />
        <span className={`font-medium text-gray-800 dark:text-gray-100`}>
          {label}
        </span>
      </div>
    </Link>
  );
};

export default SideBar;

// 1.40


================================================
FILE: client/components/table-view/index.tsx
================================================
import { columns } from "@/components/data/columns";
import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetTasksQuery } from "@/state/api";
import { DataGrid } from "@mui/x-data-grid";
import { Spinner } from "../global/loader/spinner";
import Header from "../Header";
import { useAppSelector } from "../wrapper/redux";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function TableView({ id, setIsModelNewTasOpen }: Props) {
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
  const {
    data: tasks,
    error,
    isLoading,
  } = useGetTasksQuery({ projectId: Number(id) });

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="h-[540px] w-full px-4 pb-8 xl:px-6">
      <div className="pt-5">
        <Header
          name="Table"
          buttonComponent={
            <button
              className="flex items-center rounded-md bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              Add Task
            </button>
          }
          isSmallText
        />
      </div>
      <DataGrid
        rows={tasks || []}
        columns={columns}
        className={dataGridClassNames}
        sx={dataGridSxStyles(isDarkMode)}
      />
    </div>
  );
}

export default TableView;


================================================
FILE: client/components/team-page/index.tsx
================================================
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetTeamsQuery } from "@/state/api";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { CustomToolbar } from "../data/columns";
import { Spinner } from "../global/loader/spinner";
import Header from "../Header";
import { useAppSelector } from "../wrapper/redux";

type Props = {};

const columns: GridColDef[] = [
  { field: "id", headerName: "Team ID", width: 100 },
  { field: "teamName", headerName: "Team Name", width: 150 },
  { field: "productOwnerUsername", headerName: "Product Owner", width: 200 },
  {
    field: "projectManagerUsername",
    headerName: "Project Manager",
    width: 200,
  },
];

function TeamPage({}: Props) {
  const { data: teams, isLoading, isError } = useGetTeamsQuery();
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  if (isLoading) return <Spinner />;
  if (isError) return <div>An error has occurred</div>;

  return (
    <div className="flex w-full flex-col p-8">
      <Header name="Users" />
      <DataGrid
        rows={teams || []}
        columns={columns}
        pagination
        slots={{
          toolbar: CustomToolbar,
        }}
        className={dataGridClassNames}
        sx={dataGridSxStyles(isDarkMode)}
      />
    </div>
  );
}

export default TeamPage;


================================================
FILE: client/components/timeline/index.tsx
================================================
"use client";

import { useGetProjectsQuery } from "@/state/api";
import { TaskTypeItems } from "@/types/type";
import { DisplayOption, Gantt, ViewMode } from "gantt-task-react";
import "gantt-task-react/dist/index.css";
import React, { useMemo, useState } from "react";
import { Spinner } from "../global/loader/spinner";
import { useAppSelector } from "../wrapper/redux";
import Header from "../Header";

type Props = {};

function TimeLinePage({}: Props) {
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
  const { data: projects, isError, isLoading } = useGetProjectsQuery();

  const [displayOptions, setDisplayOptions] = useState<DisplayOption>({
    viewMode: ViewMode.Month,
    locale: "en-US",
  });

  const ganttTasks = useMemo(() => {
    return (
      projects?.map((project) => ({
        start: new Date(project.startDate as string),
        end: new Date(project.endDate as string),
        name: project.name,
        id: `Project-${project.id}`,
        type: "project" as TaskTypeItems,
        progress: 50,
        isDisabled: false,
      })) || []
    );
  }, [projects]);

  const handleViewModeChange = (
    event: React.ChangeEvent<HTMLSelectElement>,
  ) => {
    setDisplayOptions((prevOptions) => ({
      ...prevOptions,
      viewMode: event.target.value as ViewMode,
    }));
  };

  if (isLoading) return <Spinner />;
  if (isError || !projects)
    return <div>An error occurred while fetching projects</div>;

  return (
    <div className="max-w-full p-8">
      <header className="mb-4 flex items-center justify-between">
        <Header name="Projects Timeline" />
        <div className="relative inline-block w-64">
          <select
            className="focus:shadow-outline block w-full appearance-none rounded border border-gray-400 bg-white px-4 py-2 pr-8 leading-tight shadow hover:border-gray-500 focus:outline-none dark:border-dark-secondary dark:bg-dark-secondary dark:text-white"
            value={displayOptions.viewMode}
            onChange={handleViewModeChange}
          >
            <option value={ViewMode.Day}>Day</option>
            <option value={ViewMode.Week}>Week</option>
            <option value={ViewMode.Month}>Month</option>
          </select>
        </div>
      </header>

      <div className="overflow-hidden rounded-md bg-white shadow dark:bg-dark-secondary dark:text-white">
        <div className="timeline">
          <Gantt
            tasks={ganttTasks}
            {...displayOptions}
            columnWidth={displayOptions.viewMode === ViewMode.Month ? 150 : 100}
            listCellWidth="100px"
            projectBackgroundColor={isDarkMode ? "#101214" : "#1f2937"}
            projectProgressColor={isDarkMode ? "#1f2937" : "#aeb8c2"}
            projectProgressSelectedColor={isDarkMode ? "#000" : "#9ba1a6"}
          />
        </div>
      </div>
    </div>
  );
}

export default TimeLinePage;


================================================
FILE: client/components/timeline-view/index.tsx
================================================
import { useGetTasksQuery } from "@/state/api";
import { DisplayOption, Gantt, ViewMode } from "gantt-task-react";
import "gantt-task-react/dist/index.css";
import React, { useMemo, useState } from "react";
import { Spinner } from "../global/loader/spinner";
import { useAppSelector } from "../wrapper/redux";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

type TaskTypeItems = "task" | "milestone" | "project";

function Timeline({ id, setIsModelNewTasOpen }: Props) {
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  const {
    data: tasks,
    error,
    isLoading,
  } = useGetTasksQuery({ projectId: Number(id) });

  const [displayOptions, setDisplayOptions] = useState<DisplayOption>({
    viewMode: ViewMode.Month,
    locale: "en-US",
  });

  const ganttTasks = useMemo(() => {
    return (
      tasks?.map((task) => ({
        start: new Date(task.startDate as string),
        end: new Date(task.dueDate as string),
        name: task.title,
        id: `Task-${task.id}`,
        type: "task" as TaskTypeItems,
        progress: task.points ? (task.points / 100) * 100 : 0,
        isDisabled: false,
      })) || []
    );
  }, [tasks]);

  const handleViewModeChange = (
    event: React.ChangeEvent<HTMLSelectElement>,
  ) => {
    setDisplayOptions((prevOptions) => ({
      ...prevOptions,
      viewMode: event.target.value as ViewMode,
    }));
  };

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="px-4 xl:px-6">
      <div className="flex flex-wrap items-center justify-between gap-2 py-5">
        <h1 className="me-2 text-lg font-bold dark:text-white">
          Project Tasks Timeline
        </h1>
        <div className="relative inline-block w-64">
          <select
            className="focus:shadow-outline block w-full appearance-none rounded border border-gray-400 bg-white px-4 py-2 pr-8 leading-tight shadow hover:border-gray-500 focus:outline-none dark:border-dark-secondary dark:bg-dark-secondary dark:text-white"
            value={displayOptions.viewMode}
            onChange={handleViewModeChange}
          >
            <option value={ViewMode.Day}>Day</option>
            <option value={ViewMode.Week}>Week</option>
            <option value={ViewMode.Month}>Month</option>
          </select>
        </div>
      </div>

      <div className="overflow-hidden rounded-md bg-white shadow dark:bg-dark-secondary dark:text-white">
        <div className="timeline">
          <Gantt
            tasks={ganttTasks}
            {...displayOptions}
            columnWidth={displayOptions.viewMode === ViewMode.Month ? 150 : 100}
            listCellWidth="100px"
            barBackgroundColor={isDarkMode ? "#101214" : "#aeb8c2"}
            barBackgroundSelectedColor={isDarkMode ? "#000" : "#9ba1a6"}
          />
        </div>
        <div className="px-4 pb-5 pt-1">
          <button
            className="flex items-center rounded bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
            onClick={() => setIsModelNewTasOpen(true)}
          >
            Add New Task
          </button>
        </div>
      </div>
    </div>
  );
}

export default Timeline;


================================================
FILE: client/components/user-card/index.tsx
================================================
import { User } from "@/types/type";
import Image from "next/image";
import React from "react";

type Props = {
  user: User;
};

function UserCard({ user }: Props) {
  return (
    <div className="flex items-center rounded border p-4 shadow">
      {user.profilePictureUrl && (
        <Image
          src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/p1.jpeg`}
          alt="profile picture"
          width={32}
          height={32}
          className="rounded-full"
        />
      )}
      <div>
        <h3>{user.username}</h3>
        <p>{user.email}</p>
      </div>
    </div>
  );
}

export default UserCard;


================================================
FILE: client/components/user-page/index.tsx
================================================
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetUsersQuery } from "@/state/api";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import Image from "next/image";
import { CustomToolbar } from "../data/columns";
import { Spinner } from "../global/loader/spinner";
import Header from "../Header";
import { useAppSelector } from "../wrapper/redux";

type Props = {};

const columns: GridColDef[] = [
  { field: "userId", headerName: "ID", width: 100 },
  { field: "username", headerName: "Username", width: 150 },
  {
    field: "profilePictureUrl",
    headerName: "Profile Picture",
    width: 100,
    renderCell: (params) => (
      <div className="flex h-full w-full items-center justify-center">
        <div className="h-9 w-9">
          <Image
            src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${params.value}`}
            alt={params.row.username}
            width={100}
            height={50}
            className="h-full rounded-full object-cover"
          />
        </div>
      </div>
    ),
  },
];

function UserPage({}: Props) {
  const { data: users, isLoading, isError } = useGetUsersQuery();
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  if (isLoading) return <Spinner />;
  if (isError) return <div>An error has occurred</div>;

  return (
    <div className="flex w-full flex-col p-8">
      <Header name="Users" />
      <DataGrid
        rows={users || []}
        columns={columns}
        getRowId={(row) => row.userId}
        pagination
        slots={{
          toolbar: CustomToolbar,
        }}
        className={dataGridClassNames}
        sx={dataGridSxStyles(isDarkMode)}
      />
    </div>
  );
}

export default UserPage;


================================================
FILE: client/components/wrapper/dashboardWrapper.tsx
================================================
"use client";

import Navbar from "@/components/navbar";
import SideBar from "@/components/sidebar";
import React, { useEffect } from "react";
import AuthProvider from "../global/auth-provider";
import StoreProvider, { useAppSelector } from "./redux";

type Props = {
  children: React.ReactNode;
};

function DashboardLayout({ children }: Props) {
  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed,
  );
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  useEffect(() => {
    if (isDarkMode) {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }
  });

  return (
    <div className="flex min-h-screen w-full bg-gray-50 text-gray-900">
      <SideBar />
      <main
        className={`flex w-full flex-col bg-gray-50 dark:bg-dark-bg ${isSidebarCollapsed ? "" : "md:pl-64"}`}
      >
        <Navbar />
        {children}
      </main>
    </div>
  );
}

const DashboardWrapper = ({ children }: { children: React.ReactNode }) => {
  return (
    <StoreProvider>
      <AuthProvider>
        <DashboardLayout>{children}</DashboardLayout>
      </AuthProvider>
    </StoreProvider>
  );
};

export default DashboardWrapper;


================================================
FILE: client/components/wrapper/redux.tsx
================================================
import globalReducer from "@/state";
import { api } from "@/state/api";
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { useRef } from "react";
import {
  Provider,
  TypedUseSelectorHook,
  useDispatch,
  useSelector,
} from "react-redux";
import {
  FLUSH,
  PAUSE,
  PERSIST,
  persistReducer,
  persistStore,
  PURGE,
  REGISTER,
  REHYDRATE,
} from "redux-persist";
import { PersistGate } from "redux-persist/integration/react";
import createWebStorage from "redux-persist/lib/storage/createWebStorage";

/* REDUX PERSISTENCE */
const createNoopStorage = () => {
  return {
    getItem(_key: any) {
      return Promise.resolve(null);
    },
    setItem(_key: any, value: any) {
      return Promise.resolve(value);
    },
    removeItem(_key: any) {
      return Promise.resolve();
    },
  };
};

const storage =
  typeof window === "undefined"
    ? createNoopStorage()
    : createWebStorage("local");

const persistConfig = {
  key: "root",
  storage,
  whitelist: ["global"],
};
const rootReducer = combineReducers({
  global: globalReducer,
  [api.reducerPath]: api.reducer,
});
const persistedReducer = persistReducer(persistConfig, rootReducer);

/* REDUX STORE */
export const makeStore = () => {
  return configureStore({
    reducer: persistedReducer,
    // @ts-ignore
    middleware: (getDefault) =>
      getDefault({
        serializableCheck: {
          ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
        },
      }).concat(api.middleware),
  });
};

/* REDUX TYPES */
export type AppStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<AppStore["getState"]>;
export type AppDispatch = AppStore["dispatch"];
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

/* PROVIDER */
export default function StoreProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const storeRef = useRef<AppStore>();
  if (!storeRef.current) {
    storeRef.current = makeStore();
    setupListeners(storeRef.current.dispatch);
  }
  const persistor = persistStore(storeRef.current);

  return (
    <Provider store={storeRef.current}>
      <PersistGate loading={null} persistor={persistor}>
        {children}
      </PersistGate>
    </Provider>
  );
}


================================================
FILE: client/lib/utils.ts
================================================
export const dataGridClassNames =
  "border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200";

export const dataGridSxStyles = (isDarkMode: boolean) => {
  return {
    "& .MuiDataGrid-columnHeaders": {
      color: `${isDarkMode ? "#e5e7eb" : ""}`,
      '& [role="row"] > *': {
        backgroundColor: `${isDarkMode ? "#1d1f21" : "white"}`,
        borderColor: `${isDarkMode ? "#2d3135" : ""}`,
      },
    },
    "& .MuiIconbutton-root": {
      color: `${isDarkMode ? "#a3a3a3" : ""}`,
    },
    "& .MuiTablePagination-root": {
      color: `${isDarkMode ? "#a3a3a3" : ""}`,
    },
    "& .MuiTablePagination-selectIcon": {
      color: `${isDarkMode ? "#a3a3a3" : ""}`,
    },
    "& .MuiDataGrid-cell": {
      border: "none",
    },
    "& .MuiDataGrid-row": {
      borderBottom: `1px solid ${isDarkMode ? "#2d3135" : "e5e7eb"}`,
    },
    "& .MuiDataGrid-withBorderColor": {
      borderColor: `${isDarkMode ? "#2d3135" : "e5e7eb"}`,
    },
  };
};


================================================
FILE: client/next.config.mjs
================================================
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "sh-s3-images.s3.us-east-1.amazonaws.com",
        port: "",
        pathname: "/**",
      },
    ],
  },
};

export default nextConfig;


================================================
FILE: client/package.json
================================================
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@aws-amplify/ui-react": "^6.9.0",
    "@emotion/react": "^11.14.0",
    "@emotion/styled": "^11.14.0",
    "@mui/material": "^6.3.0",
    "@mui/x-data-grid": "^7.23.5",
    "@reduxjs/toolkit": "^2.5.0",
    "aws-amplify": "^6.12.1",
    "axios": "^1.7.9",
    "date-fns": "^4.1.0",
    "dotenv": "^16.4.7",
    "gantt-task-react": "^0.3.9",
    "lodash": "^4.17.21",
    "lucide-react": "^0.469.0",
    "next": "14.2.7",
    "numeral": "^2.0.6",
    "react": "^18",
    "react-dnd": "^16.0.1",
    "react-dnd-html5-backend": "^16.0.1",
    "react-dom": "^18",
    "react-redux": "^9.2.0",
    "recharts": "^2.15.0",
    "redux-persist": "^6.0.0"
  },
  "devDependencies": {
    "@types/lodash": "^4.17.13",
    "@types/node": "^20",
    "@types/numeral": "^2.0.5",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@types/uuid": "^10.0.0",
    "eslint": "^8",
    "eslint-config-next": "14.2.7",
    "postcss": "^8",
    "prettier": "^3.4.2",
    "prettier-plugin-tailwindcss": "^0.6.9",
    "tailwind-merge": "^2.6.0",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  }
}


================================================
FILE: client/postcss.config.mjs
================================================
/** @type {import('postcss-load-config').Config} */
const config = {
  plugins: {
    tailwindcss: {},
  },
};

export default config;


================================================
FILE: client/state/api.ts
================================================
import {
  ProjectTypes,
  SearchResults,
  TasksTypes,
  Team,
  User,
} from "@/types/type";
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { fetchAuthSession, getCurrentUser } from "aws-amplify/auth";

export const api = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: process.env.NEXT_PUBLIC_BASE_URL,
    prepareHeaders: async (headers) => {
      const session = await fetchAuthSession();
      const { accessToken } = session.tokens ?? {};

      if (accessToken) {
        headers.set("Authorization", `Bearer ${accessToken}`);
      }

      return headers;
    },
  }),
  reducerPath: "api",
  tagTypes: ["Projects", "Tasks", "Users", "Teams"],
  endpoints: (build) => ({
    getAuthUser: build.query({
      queryFn: async (_, _queryApi, _extraoptions, fetchWihBQ) => {
        try {
          const user = await getCurrentUser();
          const session = await fetchAuthSession();

          if (!session) throw new Error("No session found");

          const { userSub } = session;
          const { accessToken } = session.tokens ?? {};

          const userDetailsResponse = await fetchWihBQ(`users/${userSub}`);
          const userDetails = userDetailsResponse.data as User;

          return { data: { user, userSub, userDetails } };
        } catch (error: any) {
          return { error: error.message || "could not fetch user data" };
        }
      },
    }),
    getProjects: build.query<ProjectTypes[], void>({
      query: () => "projects",
      providesTags: ["Projects"],
    }),
    createProject: build.mutation<ProjectTypes, Partial<ProjectTypes>>({
      query: (project) => ({
        url: "projects",
        method: "POST",
        body: project,
      }),
      invalidatesTags: ["Projects"],
    }),
    getTasks: build.query<TasksTypes[], { projectId: number }>({
      query: ({ projectId }) => `tasks?projectId=${projectId}`,
      providesTags: (result) =>
        result
          ? result.map(({ id }) => ({ type: "Tasks" as const, id }))
          : [{ type: "Tasks" as const }],
    }),
    getTasksByUser: build.query<TasksTypes[], number>({
      query: (userId) => `tasks/user/${userId}`,
      providesTags: (result, error, userId) =>
        result
          ? result.map(({ id }) => ({ type: "Tasks", id }))
          : [{ type: "Tasks", id: userId }],
    }),
    createTasks: build.mutation<TasksTypes, Partial<TasksTypes>>({
      query: (task) => ({
        url: "tasks",
        method: "POST",
        body: task,
      }),
      invalidatesTags: ["Tasks"],
    }),
    updateTasks: build.mutation<TasksTypes, { taskId: number; status: string }>(
      {
        query: ({ taskId, status }) => ({
          url: `tasks/${taskId}/status`,
          method: "PATCH",
          body: { status },
        }),
        invalidatesTags: (result, error, { taskId }) => [
          { type: "Tasks", id: taskId },
        ],
      },
    ),
    getTeams: build.query<Team[], void>({
      query: () => "teams",
      providesTags: ["Teams"],
    }),
    getUsers: build.query<User[], void>({
      query: () => "users",
      providesTags: ["Users"],
    }),
    search: build.query<SearchResults, string>({
      query: (query) => `search?query=${query}`,
    }),
  }),
});

export const {
  useGetProjectsQuery,
  useCreateProjectMutation,
  useGetTasksQuery,
  useCreateTasksMutation,
  useUpdateTasksMutation,
  useSearchQuery,
  useGetUsersQuery,
  useGetTeamsQuery,
  useGetTasksByUserQuery,
  useGetAuthUserQuery,
} = api;


================================================
FILE: client/state/index.ts
================================================
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

export interface initialStateTypes {
  isSidebarCollapsed: boolean;
  isDarkMode: boolean;
}

const initialState: initialStateTypes = {
  isSidebarCollapsed: false,
  isDarkMode: false,
};

export const globalSlice = createSlice({
  name: "global",
  initialState,
  reducers: {
    setIsSidebarCollapsed: (state, action: PayloadAction<boolean>) => {
      state.isSidebarCollapsed = action.payload;
    },
    setIsDarkMode: (state, action: PayloadAction<boolean>) => {
      state.isDarkMode = action.payload;
    },
  },
});

export const { setIsSidebarCollapsed, setIsDarkMode } = globalSlice.actions;
export default globalSlice.reducer;


================================================
FILE: client/tailwind.config.ts
================================================
import type { Config } from "tailwindcss";

export default {
  darkMode: "class",
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        white: "#ffffff",
        gray: {
          100: "#f3f4f6",
          200: "#e5e7eb",
          300: "#d1d5db",
          500: "#6b7280",
          700: "#374151",
          800: "#1f2937",
        },
        blue: {
          200: "#93c5fd",
          400: "#60a5fa",
          500: "#3b82f6",
        },
        "dark-bg": "#101214",
        "dark-secondary": "#1d1f21",
        "dark-tertiary": "#3b3d40",
        "blue-primary": "#0275ff",
        "stroke-dark": "#2d3135",
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [],
} satisfies Config;


================================================
FILE: client/tsconfig.json
================================================
{
  "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,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": ["./*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}


================================================
FILE: client/types/type.ts
================================================
export interface ProjectTypes {
  id: number;
  name: string;
  description?: string;
  startDate?: string;
  endDate?: string;
}

export enum Status {
  ToDo = "To Do",
  WorkInProgress = "Work In Progress",
  UnderReview = "Under Review",
  Completed = "Completed",
}

export enum Priority {
  Urgent = "Urgent",
  High = "High",
  Medium = "Medium",
  Low = "Low",
  Backlog = "Backlog",
}

export interface User {
  userId?: number;
  username: string;
  email: string;
  profilePictureUrl?: string;
  cognitoId?: string;
  teamId?: number;
}

export interface Attachment {
  id: number;
  fileURL: string;
  fileName: string;
  taskId: number;
  uploadedById: number;
}

export interface TasksTypes {
  id: number;
  title: string;
  description?: string;
  status?: Status;
  priority?: Priority;
  tags?: string;
  startDate?: string;
  dueDate?: string;
  points?: number;
  projectId: number;
  authorUserId?: number;
  assignedUserId?: number;

  author?: User;
  assignee?: User;
  comments?: Comment[];
  attachments?: Attachment[];
}

export interface SearchResults {
  tasks?: TasksTypes[];
  projects?: ProjectTypes[];
  users?: User[];
}

export interface Team {
  teamId: number;
  teamName: string;
  productOwnerUserId?: number;
  projectManagerUserId?: number;
}

export type TaskTypeItems = "task" | "milestone" | "project";


================================================
FILE: lamda_trigger.mjs
================================================
import https from "node:https";

export const handler = async (event) => {
  const postdata = JSON.stringify({
    username:
      event.request.userAttributes["preferred_username"] || event.userName,
    cognitoId: event.userName,
    profilePictureUrl: "i1.jpg",
    teamId: 1,
  });

  const opctions = {
    hostname: "https://2yk8eg8yxd.execute-api.us-east-1.amazonaws.com/prod",
    port: 443,
    path: "/create-user",
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Content-Length": postdata.length,
    },
  };

  const responseBody = await new Promise((resolve, reject) => {
    const req = https.request(opctions, (res) => {
      /* console.log(`statusCode: ${res.statusCode}`) */

      res.setEncoding("utf8");
      let body = "";
      res.on("data", (chunk) => (body += chunk));
      res.on("end", () => resolve(body));
    });

    req.on("error", reject);
    req.write(postdata);
    req.end();
  });

  return event();
};


================================================
FILE: production-level-application/.eslintrc.json
================================================
{
  "extends": "next/core-web-vitals"
}


================================================
FILE: production-level-application/.gitignore
================================================
# 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


================================================
FILE: production-level-application/README.md
================================================
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.


================================================
FILE: production-level-application/actions/index.ts
================================================
import { currentUser } from "@clerk/nextjs/server";
import { redirect } from "next/navigation";

export const onCurrentUser = async () => {
  const user = await currentUser();
  if (!user) return redirect("/");

  return user;
};


================================================
FILE: production-level-application/app/(auth)/layout.tsx
================================================
import React from "react";

type Props = {
  children: React.ReactNode;
};

function Layout({ children }: Props) {
  return (
    <div className="h-screen flex justify-center items-center">{children}</div>
  );
}

export default Layout;


================================================
FILE: production-level-application/app/(auth)/sign-in/[[...sign-in]]/page.tsx
================================================
import { SignIn } from "@clerk/nextjs";
import React from "react";

type Props = {};

function Page({}: Props) {
  return <SignIn />;
}

export default Page;


================================================
FILE: production-level-application/app/(auth)/sign-up/[[...sign-up]]/page.tsx
================================================
import { SignUp } from "@clerk/nextjs";
import React from "react";

type Props = {};

function Page({}: Props) {
  return <SignUp />;
}

export default Page;


================================================
FILE: production-level-application/app/api/move/[taskId]/route.tsx
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

export async function PATCH(
  request: Request,
  { params }: { params: { taskId?: string } }
) {
  const { taskId } = params;
  const body = await request.json();
  const { status } = body;

  if (!taskId)
    return NextResponse.json({ error: "Missing taskId" }, { status: 400 });

  try {
    const updateTasks = await prisma.task.update({
      where: {
        id: taskId,
      },
      data: {
        status: status,
      },
    });

    return NextResponse.json(updateTasks);
  } catch (error: any) {
    return NextResponse.json(
      {
        error: `Failed to update task ${error.message}`,
      },
      { status: 500 }
    );
  }
}

export async function DELETE(
  request: Request,
  { params }: { params: { taskId?: string } }
) {
  const { taskId } = params;

  if (!taskId)
    return NextResponse.json({ error: "Missing taskId" }, { status: 401 });

  try {
    const deleteTask = await prisma.task.delete({
      where: {
        id: taskId,
      },
    });

    return NextResponse.json(deleteTask, { status: 200 });
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 400 });
  }
}


================================================
FILE: production-level-application/app/api/projects/[projectId]/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

export async function DELETE(
  request: Request,
  { params }: { params: { projectId?: string } }
) {
  const { projectId } = params;

  if (!projectId)
    return NextResponse.json({ error: "Missing projectId" }, { status: 400 });

  try {
    const deleteTask = await prisma.project.delete({
      where: {
        id: projectId,
      },
    });
    return NextResponse.json(deleteTask);
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 400 });
  }
}

export async function PATCH(
  request: Request,
  { params }: { params: { projectId?: string } }
) {
  const { projectId } = params;
  const body = await request.json();
  const { userId } = body;

  if (!projectId)
    return NextResponse.json({ error: "Missing projectId" }, { status: 400 });

  try {
    const checkItsAvailable = await prisma.project.findUnique({
      where: {
        id: projectId,
        authorsIds: {
          has: userId,
        },
      },
    });

    if (checkItsAvailable)
      return NextResponse.json(
        { error: "Your Already In Project Or Current Project Not available!" },
        { status: 401 }
      );

    const updateProject = await prisma.project.update({
      where: {
        id: projectId,
      },
      data: {
        authorsIds: {
          push: userId,
        },
      },
    });

    return NextResponse.json(updateProject, { status: 200 });
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 400 });
  }
}


================================================
FILE: production-level-application/app/api/projects/route.ts
================================================
import { onCurrentUser } from "@/actions";
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

export async function GET(request: Request) {
  const user = await onCurrentUser();

  const currentUserId = await prisma.user.findUnique({
    where: {
      clerkId: user.id,
    },
  });

  if (!currentUserId)
    return NextResponse.json({ error: "User not found" }, { status: 404 });

  try {
    const project = await prisma.project.findMany({
      where: {
        authorsIds: {
          has: currentUserId.id,
        },
      },
    });
    return NextResponse.json(project);
  } catch (error: any) {
    return NextResponse.json(
      { error: `Failed to fetch projects ${error.message}` },
      { status: 500 }
    );
  }
}

export async function POST(request: Request) {
  const body = await request.json();
  const { name, description, startDate, endDate, user } = body;

  try {
    const createUser = await prisma.user.findFirst({
      where: {
        clerkId: user,
      },
    });

    if (!createUser?.id)
      return NextResponse.json({ error: "User not found" }, { status: 404 });

    const newProject = await prisma.project.create({
      data: {
        name,
        description,
        startDate,
        endDate,
        userId: createUser?.id,
        authorsIds: [createUser?.id],
      },
    });

    return NextResponse.json({ newProject }, { status: 201 });
  } catch (error: any) {
    return NextResponse.json(
      { error: `Failed to create project ${error.message}` },
      { status: 500 }
    );
  }
}


================================================
FILE: production-level-application/app/api/tasks/[projectId]/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

interface IParams {
  projectId?: string;
}

export async function GET(request: Request, { params }: { params: IParams }) {
  const { projectId } = params;

  if (!projectId)
    return NextResponse.json({ error: "Missing projectId" }, { status: 400 });

  try {
    const tasks = await prisma.task.findMany({
      where: {
        projectId: projectId,
      },
      include: {
        author: true,
        comments: true,
        attachments: true,
      },
    });

    return NextResponse.json(tasks);
  } catch (error: any) {
    return NextResponse.json(
      {
        error: `Failed to fetch tasks ${error.message}`,
      },
      { status: 500 }
    );
  }
}

export async function PATCH(
  request: Request,
  { params }: { params: { projectId?: string } }
) {
  const { projectId } = params;
  const body = await request.json();
  const { userId } = body;

  if (!projectId || !userId)
    return NextResponse.json(
      { error: "Missing projectId or userId" },
      { status: 400 }
    );

  try {
    const project = await prisma.project.findUnique({
      where: {
        id: projectId,
      },
      select: {
        authorsIds: true,
      },
    });

    if (!project)
      return NextResponse.json({ error: "Project not found" }, { status: 404 });

    const updateUsers = project.authorsIds.filter((id) => id !== userId);

    const removeUserFromProject = await prisma.project.update({
      where: {
        id: projectId,
      },
      data: {
        authorsIds: {
          set: updateUsers,
        },
      },
    });

    return NextResponse.json(removeUserFromProject);
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}


================================================
FILE: production-level-application/app/api/tasks/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const body = await request.json();

  const {
    title,
    description,
    status,
    priority,
    tags,
    startDate,
    dueDate,
    points,
    projectId,
    authorUserId,
    imageSrc,
    userId,
  } = body;

  try {
    const newTask = await prisma.task.create({
      data: {
        title,
        description,
        status,
        priority,
        tags,
        startDate,
        dueDate,
        points,
        projectId,
        authorUserId,
        imageSrc,
        userId,
      },
      include: {
        author: true,
      },
    });

    return NextResponse.json({ newTask }, { status: 201 });
  } catch (error: any) {
    console.log(error.message);

    return NextResponse.json(
      { error: `Failed to create task ${error.message}` },
      { status: 500 }
    );
  }
}


================================================
FILE: production-level-application/app/api/tasks/user/[userId]/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

interface IParams {
  userId?: string;
}

export async function GET(request: Request, { params }: { params: IParams }) {
  const { userId } = params;

  try {
    const tasks = await prisma.task.findMany({
      where: {
        OR: [{ authorUserId: userId }, { assignedUserId: userId }],
      },
      include: {
        author: true,
      },
    });
    return NextResponse.json(tasks);
  } catch (error: any) {
    return NextResponse.json(
      { error: `Failed to get user tasks ${error.message}` },
      { status: 500 }
    );
  }
}


================================================
FILE: production-level-application/app/api/user/[userId]/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

interface IParams {
  userId?: string;
}

export async function GET(request: Request, { params }: { params: IParams }) {
  const { userId } = params;

  try {
    const findUser = await prisma.user.findFirst({
      where: {
        clerkId: userId,
      },
    });

    return NextResponse.json(findUser);
  } catch (error: any) {
    return NextResponse.json({ error: "User not found" }, { status: 404 });
  }
}


================================================
FILE: production-level-application/app/api/user/route.ts
================================================
import prisma from "@/lib/prismadb";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  try {
    const body = await request.json();

    const { firstName, secondName, clerkId, profilePictureUrl } = body;

    const checkUser = await prisma.user.findUnique({
      where: { clerkId },
    });

    if (checkUser) {
      return NextResponse.json(
        { error: "User already exists" },
        { status: 404 }
      );
    } else {
      const newUsers = await prisma.user.create({
        data: {
          firstName,
          secondName,
          clerkId,
          profilePictureUrl,
        },
      });
      return NextResponse.json({
        message: "User created successfully",
        newUsers,
      });
    }
  } catch (error: any) {
    return NextResponse.json(
      {
        error: `Failed to fetch users ${error.message}`,
      },
      { status: 500 }
    );
  }
}


================================================
FILE: production-level-application/app/dashboard/layout.tsx
================================================
import DashboardWrapper from "@/components/wrapper/dashboardWrapper";
import React from "react";
import { ToastContainer } from "react-toastify";

type Props = {
  children: React.ReactNode;
};

function layout({ children }: Props) {
  return (
    <DashboardWrapper>
      <ToastContainer />
      {children}
    </DashboardWrapper>
  );
}

export default layout;


================================================
FILE: production-level-application/app/dashboard/loading.tsx
================================================
import { Spinner } from "@/components/global/loader/spinner";

type Props = {};

function Loading({}: Props) {
  return <Spinner />;
}

export default Loading;


================================================
FILE: production-level-application/app/dashboard/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import RootHomePage from "@/components/home-page/root-home-page";

type Props = {};

async function Page({}: Props) {
  return (
    <ClientOnly>
      <RootHomePage />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/priority/backlog/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import PriorityPage from "@/components/priority-page";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <PriorityPage priority={Priority.Backlog} />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/priority/high/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import PriorityPage from "@/components/priority-page";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <PriorityPage priority={Priority.High} />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/priority/low/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import PriorityPage from "@/components/priority-page";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <PriorityPage priority={Priority.Low} />;
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/priority/medium/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import PriorityPage from "@/components/priority-page";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <PriorityPage priority={Priority.Medium} />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/priority/urgent/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import PriorityPage from "@/components/priority-page";
import { Priority } from "@/types/type";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <PriorityPage priority={Priority.Urgent} />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/projects/[id]/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import ProjectPage from "@/components/global/project-page";

type Props = {
  params: {
    id: string;
  };
};

function Page({ params }: Props) {
  const { id } = params;

  return (
    <ClientOnly>
      <ProjectPage id={id} />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/dashboard/timeline/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import TimeLinePage from "@/components/timeline";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <TimeLinePage />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/app/globals.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body,
#root,
.app {
  height: 100%;
  width: 100%;
  @apply text-sm;
  @apply bg-gray-500;
  @apply text-gray-900;
}

.timeline ._3_ygE {
  @apply rounded-tl-md border border-r-0 border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._2eZzQ {
  @apply border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._2dZTy {
  @apply fill-white dark:fill-dark-secondary;
}
.timeline ._2dZTy:nth-child(even) {
  @apply fill-[#f5f5f5] dark:fill-dark-tertiary;
}
.timeline ._35nLX {
  @apply fill-white stroke-[#e6e4e4] dark:fill-dark-secondary dark:stroke-stroke-dark;
}
.timeline ._9w8d5 {
  @apply fill-[#333] dark:fill-white;
}
.timeline ._34SS0 {
  @apply bg-white dark:bg-dark-secondary;
}
.timeline ._34SS0:nth-of-type(even) {
  @apply bg-[#f5f5f5] dark:bg-dark-tertiary;
}
.timeline ._RuwuK,
.timeline ._3rUKi,
.timeline ._1rLuZ {
  @apply stroke-[#e6e4e4] dark:stroke-stroke-dark;
}
.timeline ._3ZbQT {
  @apply border-l-0 border-[#e6e4e4] dark:border-stroke-dark;
}
.timeline ._3T42e {
  @apply bg-white dark:bg-dark-bg;
}
.timeline ._29NTg {
  @apply dark:text-neutral-500;
}

::-webkit-scrollbar {
  width: 0px;
  height: 0px;
}


================================================
FILE: production-level-application/app/layout.tsx
================================================
import ReduxProvider from "@/provider/reduxProvider";
import { ClerkProvider } from "@clerk/nextjs";
import type { Metadata } from "next";
import { Plus_Jakarta_Sans } from "next/font/google";
import "./globals.css";

const jakarta = Plus_Jakarta_Sans({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Project Management App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body className={jakarta.className}>
          <ReduxProvider>{children}</ReduxProvider>
        </body>
      </html>
    </ClerkProvider>
  );
}


================================================
FILE: production-level-application/app/loading.tsx
================================================
import { Spinner } from "@/components/global/loader/spinner";

type Props = {};

function Loading({}: Props) {
  return <Spinner />;
}

export default Loading;


================================================
FILE: production-level-application/app/page.tsx
================================================
import ClientOnly from "@/components/global/client-only";
import HomeNavBar from "@/components/navbar/home";

type Props = {};

function Page({}: Props) {
  return (
    <ClientOnly>
      <HomeNavBar />
    </ClientOnly>
  );
}

export default Page;


================================================
FILE: production-level-application/components/data/columns.tsx
================================================
import {
  GridColDef,
  GridToolbarContainer,
  GridToolbarExport,
  GridToolbarFilterButton,
} from "@mui/x-data-grid";

export const columns: GridColDef[] = [
  {
    field: "title",
    headerName: "Title",
    width: 100,
  },
  {
    field: "description",
    headerName: "Description",
    width: 200,
  },
  {
    field: "status",
    headerName: "Status",
    width: 130,
    renderCell: (params) => (
      <span className="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800">
        {params.value}
      </span>
    ),
  },
  {
    field: "priority",
    headerName: "Priority",
    width: 75,
  },
  {
    field: "tags",
    headerName: "Tags",
    width: 130,
  },
  {
    field: "startDate",
    headerName: "Start Date",
    width: 130,
  },
  {
    field: "dueDate",
    headerName: "Due Date",
    width: 130,
  },
  {
    field: "author",
    headerName: "Author",
    width: 150,
    renderCell: (params) => params.value?.author || "Unknown",
  },
  {
    field: "assignee",
    headerName: "Assignee",
    width: 150,
    renderCell: (params) => params.value?.assignee || "Unassigned",
  },
];

export const userSettings = {
  username: "johndoe",
  email: "john.doe@example.com",
  teamName: "Development Team",
  roleName: "Developer",
};

export const CustomToolbar = () => (
  <GridToolbarContainer className="toolbar flex gap-2">
    <GridToolbarFilterButton />
    <GridToolbarExport />
  </GridToolbarContainer>
);

export const taskColumns: GridColDef[] = [
  { field: "title", headerName: "Title", width: 200 },
  { field: "status", headerName: "Status", width: 150 },
  { field: "priority", headerName: "Priority", width: 150 },
  { field: "dueDate", headerName: "Due Date", width: 150 },
];

export const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];

export const priorityColumns: GridColDef[] = [
  {
    field: "title",
    headerName: "Title",
    width: 100,
  },
  {
    field: "description",
    headerName: "Description",
    width: 200,
  },
  {
    field: "status",
    headerName: "Status",
    width: 130,
    renderCell: (params) => (
      <span className="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800">
        {params.value}
      </span>
    ),
  },
  {
    field: "priority",
    headerName: "Priority",
    width: 75,
  },
  {
    field: "tags",
    headerName: "Tags",
    width: 130,
  },
  {
    field: "startDate",
    headerName: "Start Date",
    width: 130,
  },
  {
    field: "dueDate",
    headerName: "Due Date",
    width: 130,
  },
  {
    field: "author",
    headerName: "Author",
    width: 150,
    renderCell: (params) => params.value?.username || "Unknown",
  },
  {
    field: "assignee",
    headerName: "Assignee",
    width: 150,
    renderCell: (params) => params.value?.username || "Unassigned",
  },
];

export const formFields = {
  signUp: {
    username: {
      order: 1,
      placeholder: "Choose a username",
      label: "Username",
      inputProps: { required: true },
    },
    email: {
      order: 1,
      placeholder: "Enter your email address",
      label: "Email",
      inputProps: { type: "email", required: true },
    },
    password: {
      order: 3,
      placeholder: "Enter your password",
      label: "Password",
      inputProps: { type: "password", required: true },
    },
    confirm_password: {
      order: 4,
      placeholder: "Confirm your password",
      label: "Confirm Password",
      inputProps: { type: "password", required: true },
    },
  },
};


================================================
FILE: production-level-application/components/global/border-view/index.tsx
================================================
import { useGetTasksQuery, useUpdateTasksMutation } from "@/state/api";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { Spinner } from "../loader/spinner";
import TaskColumn from "../task-column";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

const taskStatus = ["To Do", "Work In Progress", "Under Review", "Completed"];

function BorderView({ id, setIsModelNewTasOpen }: Props) {
  const { data: tasks, isLoading, error } = useGetTasksQuery({ projectId: id });

  const [updateTaskStatus] = useUpdateTasksMutation();

  const moveTask = (taskId: number, toStatus: string) => {
    updateTaskStatus({ taskId, status: toStatus });
  };

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <DndProvider backend={HTML5Backend}>
      <div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2 xl:grid-cols-4">
        {taskStatus.map((status) => (
          <TaskColumn
            key={status}
            status={status}
            tasks={tasks || []}
            moveTask={moveTask}
            setIsModelNewTasOpen={setIsModelNewTasOpen}
          />
        ))}
      </div>
    </DndProvider>
  );
}

export default BorderView;


================================================
FILE: production-level-application/components/global/client-only/index.tsx
================================================
"use client";

import { motion } from "framer-motion";

type Props = {
  children: React.ReactNode;
};

function ClientOnly({ children }: Props) {
  return (
    <motion.div
      initial={{ opacity: 0 }}
      whileInView={{ opacity: 1 }}
      viewport={{ once: true }}
    >
      {children}
    </motion.div>
  );
}

export default ClientOnly;


================================================
FILE: production-level-application/components/global/image-card/index.tsx
================================================
import { ImageCardProps } from "@/types/type";
import React from "react";

type Props = {};

function ImageCard({ src, aspectRatio, marginTop = "" }: ImageCardProps) {
  return (
    <img
      loading="lazy"
      src={src}
      alt=""
      className={`object-contain w-full aspect-[${aspectRatio}] ${marginTop}`}
    />
  );
}

export default ImageCard;


================================================
FILE: production-level-application/components/global/image-upload/index.tsx
================================================
"use client";

import { Camera, PhoneOutgoingIcon } from "lucide-react";
import { CldUploadWidget } from "next-cloudinary";
import Image from "next/image";
import React, { useCallback } from "react";

declare global {
  var cloudinary: any;
}

type Props = {
  setImageSrc: (image: { secure_url: string }) => void;
  value: string;
};

function ImageUpload({ setImageSrc, value }: Props) {
  /*   const [resource, setResource] = React.useState<any | null>(null);
  console.log("🚀 ~ ImageUpload ~ resource:", resource.secure_url); */
  /*   const handleCallback = useCallback(
    (result: any) => {
      onChange(result.info.secure_url);
    },
    [onchange]
  ); */

  return (
    <CldUploadWidget
      //onUpload={handleCallback}
      onSuccess={(result: any, { widget }) => {
        if (result?.info?.secure_url) {
          setImageSrc({ secure_url: result.info.secure_url });
        } else {
          console.error("Upload failed, secure_url not found");
        }
      }}
      uploadPreset="pmapppreset"
      options={{
        maxFiles: 1,
      }}
    >
      {({ open }) => {
        return (
          <div
            onClick={() => open?.()}
            className="relative cursor-pointer hover:opacity-70 transition border-dashed border-2 p-20 border-neutral-300 flex flex-col justify-center items-center gap-4 text-neutral-600 h-96"
          >
            <Camera size={50} />
            <div className="font-semibold text-lg">Click to upload</div>
            {value && (
              <div className="absolute inset-0 w-full h-full">
                <Image
                  alt="uploade"
                  fill
                  style={{ objectFit: "cover" }}
                  src={value}
                />
              </div>
            )}
          </div>
        );
      }}
    </CldUploadWidget>
  );
}

export default ImageUpload;


================================================
FILE: production-level-application/components/global/list-view/index.tsx
================================================
import { useGetTasksQuery } from "@/state/api";
import { TasksTypes } from "@/types/type";
import { Spinner } from "../loader/spinner";
import Header from "@/components/header";
import TaskCard from "../task-card";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function ListView({ id, setIsModelNewTasOpen }: Props) {
  const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId: id });

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="px-4 pb-8 xl:px-6">
      <div className="pt-5">
        <Header
          name="List"
          buttonComponent={
            <button
              className="hove:bg-blue-600 flex items-center rounded-md bg-blue-primary px-3 py-3 text-white"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              Add Task
            </button>
          }
          isSmallText
        />
      </div>
      <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6">
        {tasks?.map((task: TasksTypes) => (
          <TaskCard key={task.id} task={task} />
        ))}
      </div>
    </div>
  );
}

export default ListView;


================================================
FILE: production-level-application/components/global/loader/buttonLoader.tsx
================================================
type SpinnerProps = {
  color?: string;
};

export const ButtonLoader = ({ color }: SpinnerProps) => {
  return (
    <div role="status" className="flex items-center justify-center">
      <svg
        aria-hidden="true"
        className="inline h-8 w-8 animate-spin fill-yellow-400 text-gray-200 dark:text-gray-600"
        viewBox="0 0 100 101"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
          fill={color || "#fff"}
        />
        <path
          d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
          fill={color || "#fff"}
        />
      </svg>
    </div>
  );
};


================================================
FILE: production-level-application/components/global/loader/spinner.tsx
================================================
type SpinnerProps = {
  color?: string;
};

export const Spinner = ({ color }: SpinnerProps) => {
  return (
    <div
      role="status"
      className="flex h-screen w-screen items-center justify-center"
    >
      <svg
        aria-hidden="true"
        className="inline h-8 w-8 animate-spin fill-yellow-400 text-gray-200 dark:text-gray-600"
        viewBox="0 0 100 101"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
          fill={color || "#fff"}
        />
        <path
          d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
          fill={color || "#fff"}
        />
      </svg>
    </div>
  );
};


================================================
FILE: production-level-application/components/global/project-header/index.tsx
================================================
import Header from "@/components/header";
import ModalNewProject from "@/components/modal/modal-new-project";
import ModelShareModel from "@/components/modal/model-share-project";
import {
  useDeleteProjectMutation,
  useGetUserQuery,
  useRemoveUserFromTaskMutation,
} from "@/state/api";
import { ProjectTypes } from "@/types/type";
import {
  Clock,
  Filter,
  Grid3x3,
  Grid3X3,
  List,
  LogOut,
  PlusSquare,
  Share2,
  Table,
  Trash2,
  Users,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "react-toastify";
import TabButton from "../tab-button";

type Props = {
  id: string;
  userId?: string;
  activeTab: string;
  projectsUserId?: ProjectTypes;
  setActiveTab: (tabName: string) => void;
};

function ProjectHeader({
  activeTab,
  setActiveTab,
  id,
  userId,
  projectsUserId,
}: Props) {
  const router = useRouter();
  const { data: user, error } = useGetUserQuery({
    userId: userId ?? "defaultUserId",
  });
  const [deleteProject] = useDeleteProjectMutation();
  const [removeUsers, { error: removeUser }] = useRemoveUserFromTaskMutation();
  const [sharedProjectId, setSharedProjectId] = useState("");
  const [isModalNameProjectOpen, setIsModalNameProjectOpen] = useState(false);
  const [isModelShareProjectOpen, setIsModelShareProjectOpen] = useState(false);

  /*   const handleUpdateAuthors = async (authorIds: string, sProjectId: string) => {
    if (!authorIds) return;
    if (!sProjectId) return;

    try {
      await updateProjectAuthors({
        projectId: sProjectId,
        userId: authorIds,
      }).then(() => setIsModalNameProjectOpen(false));
    } catch (error: any) {
      console.log("🚀 ~ handleUpdateAuthors ~ error:", error);
    }
  }; */

  const handleRemoveAuthor = async (userId: string, projectId: string) => {
    if (!userId) return;
    if (!projectId) return;

    try {
      await removeUsers({
        projectId: projectId,
        userId: userId,
      }).then(() =>
        toast.warning("Leave Project Successfully!", {
          position: "bottom-right",
        })
      );
      router.refresh();
      router.push("/dashboard");
    } catch (error: any) {
      console.error("Error removing user from Project:", error);
    }
  };

  const handleDelete = async (projectId: string) => {
    if (!projectId) {
      console.error("projectId is undefined or invalid");
      return;
    }

    try {
      deleteProject({ projectId }).then(() =>
        toast.warning("Project Delete Successfully!", {
          position: "bottom-right",
        })
      );
      router.refresh();
      router.push("/dashboard");
    } catch (error) {
      console.error("Error deleting Project:", error);
    }
  };

  return (
    <div className="px-4 xl:px-6">
      <ModalNewProject
        isOpen={isModalNameProjectOpen}
        onClose={() => setIsModalNameProjectOpen(false)}
      />
      <ModelShareModel
        id={id}
        currentUserId={String(user?.id)}
        sharedProjectId={sharedProjectId}
        setSharedProjectId={setSharedProjectId}
        isOpen={isModelShareProjectOpen}
        onClose={() => setIsModelShareProjectOpen(false)}
      />
      <div className="pb-6 pt-6 lg:pb-4 lg:pt-8">
        <Header
          name="Product Design Development"
          buttonComponent={
            <div className="flex justify-center gap-x-3">
              {/*  <CreateOrganization /> */}

              <button
                className="flex items-center rounded-md bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
                onClick={() => setIsModalNameProjectOpen(true)}
              >
                <PlusSquare className="mr-2 h-5 w-5" /> New Board
              </button>
              <button
                className="flex items-center rounded-md bg-green-400 px-3 py-2 hover:text-white hover:bg-green-600"
                onClick={() => setIsModelShareProjectOpen(true)}
              >
                <Users className="mr-2 h-5 w-5" /> Invite or Join
              </button>
              {projectsUserId?.userId === user?.id ? (
                <button
                  className="flex items-center rounded-md bg-red-300 px-3 py-2 hover:text-white hover:bg-red-600"
                  onClick={() => handleDelete(id)}
                >
                  <Trash2 className="mr-2 h-5 w-5" /> Delete
                </button>
              ) : (
                <button
                  className="flex items-center rounded-md bg-red-300 px-3 py-2 hover:text-white hover:bg-red-600"
                  onClick={() =>
                    handleRemoveAuthor(
                      String(user?.id),
                      String(projectsUserId?.id)
                    )
                  }
                >
                  <LogOut className="mr-2 h-5 w-5" /> Leave
                </button>
              )}
            </div>
          }
        />
      </div>
      <div className="flex flex-wrap-reverse gap-2 border-y border-gray-200 pb-[8px] pt-2 dark:border-stroke-dark md:items-center">
        <div className="flex flex-1 items-center gap-2 md:gap-4">
          <TabButton
            name="Board"
            icon={<Grid3X3 className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="List"
            icon={<List className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="Timeline"
            icon={<Clock className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
          <TabButton
            name="Table"
            icon={<Table className="h5 w-5" />}
            activeTab={activeTab}
            setActiveTab={setActiveTab}
          />
        </div>
        <div className="flex items-center gap-2">
          <button className="text-gray-500 hover:text-gray-600 dark:text-neutral-500 dark:hover:text-gray-300">
            <Filter className="h-5 w-5" />
          </button>
          <button className="text-gray-500 hover:text-gray-600 dark:text-neutral-500 dark:hover:text-gray-300">
            <Share2 className="h-5 w-5" />
          </button>
          <div className="relative">
            <input
              type="text"
              placeholder="Search Task"
              className="rounded-md border py-1 pl-10 pr-4 focus:outline-none dark:border-dark-secondary dark:bg-dark-secondary dark:text-white"
            />
            <Grid3x3 className="absolute left-3 top-2 h-4 w-4 text-gray-400 dark:text-neutral-500" />
          </div>
        </div>
      </div>
    </div>
  );
}

export default ProjectHeader;


================================================
FILE: production-level-application/components/global/project-page/index.tsx
================================================
"use client";

import ModelNewTask from "@/components/modal/model-new-task";
import { useGetProjectsQuery } from "@/state/api";
import { ProjectTypes } from "@/types/type";
import { useUser } from "@clerk/nextjs";
import { useEffect, useState } from "react";
import BorderView from "../border-view";
import ClientOnly from "../client-only";
import ListView from "../list-view";
import ProjectHeader from "../project-header";
import TableView from "../table-view";
import Timeline from "../timeline-view";

type Props = {
  id: string;
};

function ProjectPage({ id }: Props) {
  const { user } = useUser();
  const [activeTAB, setActiveTAB] = useState("Board");
  const [filterData, setFilterData] = useState<ProjectTypes>();
  const [isModelNewTasOpen, setIsModelNewTasOpen] = useState(false);
  const { data: projects, isLoading: isProjectsLoading } =
    useGetProjectsQuery();

  useEffect(() => {
    const filterData = projects?.find((p) => String(p.id) === String(id));
    setFilterData(filterData);
  }, [id, projects]);

  return (
    <div>
      <ModelNewTask
        id={id}
        userId={user?.id}
        isOpen={isModelNewTasOpen}
        onClose={() => setIsModelNewTasOpen(false)}
      />
      <ProjectHeader
        id={id}
        userId={user?.id}
        activeTab={activeTAB}
        setActiveTab={setActiveTAB}
        projectsUserId={filterData}
      />
      {activeTAB === "Board" && (
        <ClientOnly>
          <BorderView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
        </ClientOnly>
      )}
      {activeTAB === "List" && (
        <ClientOnly>
          <ListView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
        </ClientOnly>
      )}
      {activeTAB === "Timeline" && (
        <ClientOnly>
          <Timeline id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
        </ClientOnly>
      )}
      {activeTAB === "Table" && (
        <ClientOnly>
          <TableView id={id} setIsModelNewTasOpen={setIsModelNewTasOpen} />
        </ClientOnly>
      )}
    </div>
  );
}

export default ProjectPage;


================================================
FILE: production-level-application/components/global/tab-button/index.tsx
================================================
import React from "react";

type Props = {
  name: string;
  icon: React.ReactNode;
  setActiveTab: (tabName: string) => void;
  activeTab: string;
};

function TabButton({ activeTab, icon, name, setActiveTab }: Props) {
  const isActive = activeTab === name;

  return (
    <button
      className={`relative flex items-center gap-2 px-1 py-2 text-gray-500 after:absolute after:-bottom-[9px] after:left-0 after:h-[1px] after:w-full hover:text-blue-600 dark:text-neutral-500 dark:hover:text-white sm:px-2 lg:px-4 ${
        isActive ? "text-blue-600 after:bg-blue-600 dark:text-white" : ""
      }`}
      onClick={() => setActiveTab(name)}
    >
      {icon}
      {name}
    </button>
  );
}

export default TabButton;


================================================
FILE: production-level-application/components/global/table-view/index.tsx
================================================
import { columns } from "@/components/data/columns";
import Header from "@/components/header";
import { useAppSelector } from "@/components/wrapper/redux";
import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetTasksQuery } from "@/state/api";
import { DataGrid } from "@mui/x-data-grid";
import { Spinner } from "../loader/spinner";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function TableView({ id, setIsModelNewTasOpen }: Props) {
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
  const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId: id });

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="h-[540px] w-full px-4 pb-8 xl:px-6">
      <div className="pt-5">
        <Header
          name="Table"
          buttonComponent={
            <button
              className="flex items-center rounded-md bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              Add Task
            </button>
          }
          isSmallText
        />
      </div>
      <DataGrid
        rows={tasks || []}
        columns={columns}
        className={dataGridClassNames}
        sx={dataGridSxStyles(isDarkMode)}
      />
    </div>
  );
}

export default TableView;


================================================
FILE: production-level-application/components/global/task-card/index.tsx
================================================
import { TasksTypes } from "@/types/type";
import { format } from "date-fns";
import Image from "next/image";
import React from "react";

type Props = {
  task: TasksTypes;
};

function TaskCard({ task }: Props) {
  return (
    <div className="mb-3 rounded bg-white p-4 shadow dark:bg-dark-secondary dark:text-white">
      {task.attachments && task.attachments.length > 0 && (
        <div>
          <strong>Attachments:</strong>
          <div className="flex flex-wrap">
            {task.attachments && task.attachments.length > 0 && (
              <Image
                src={`https://sh-s3-images.s3.us-east-1.amazonaws.com/${task.attachments[0].fileURL}`}
                alt={task.attachments[0].fileName}
                width={400}
                height={200}
                className="rounded-md"
              />
            )}
          </div>
        </div>
      )}
      <p>
        <strong>ID:</strong> {task.id}
      </p>
      <p>
        <strong>Title:</strong> {task.title}
      </p>
      <p>
        <strong>Description:</strong>{" "}
        {task.description || "No description provided"}
      </p>
      <p>
        <strong>Status:</strong> {task.status}
      </p>
      <p>
        <strong>Priority:</strong> {task.priority}
      </p>
      <p>
        <strong>Tags:</strong> {task.tags || "No tags"}
      </p>
      <p>
        <strong>Start Date:</strong>{" "}
        {task.startDate ? format(new Date(task.startDate), "P") : "Not set"}
      </p>
      <p>
        <strong>Due Date:</strong>{" "}
        {task.dueDate ? format(new Date(task.dueDate), "P") : "Not set"}
      </p>
      <p>
        <strong>Author:</strong>{" "}
        {task.author ? task.author.firstName : "Unknown"}
      </p>
      <p>
        <strong>Assignee:</strong>{" "}
        {task.assignee ? task.assignee.firstName : "Unassigned"}
      </p>
    </div>
  );
}

export default TaskCard;


================================================
FILE: production-level-application/components/global/task-column/index.tsx
================================================
import { EllipsisVertical, Plus } from "lucide-react";
import React from "react";
import { useDrop } from "react-dnd";
import { TasksTypes } from "@/types/type";
import Task from "@/components/task";

type Props = {
  status: string;
  tasks: TasksTypes[];
  moveTask: (taskId: number, toStatus: string) => void;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

function TaskColumn({ moveTask, setIsModelNewTasOpen, status, tasks }: Props) {
  const [{ isOver }, drop] = useDrop(() => ({
    accept: "task",
    drop: (item: { id: number }) => moveTask(item.id, status),
    collect: (monitor: any) => ({
      isOver: !!monitor.isOver(),
    }),
  }));

  const tasksCount = tasks.filter((task) => task.status === status).length;

  const statusColor: any = {
    "To Do": "#2563EB",
    "Work In Progress": "#059669",
    "Under Review": "#D97706",
    Completed: "#000000",
  };

  return (
    <div
      ref={(instance) => {
        drop(instance);
      }}
      className={`sl:py-4 rounded-lg py-2 xl:px-2 ${
        isOver ? "bg-blue-100 dark:bg-neutral-950" : ""
      }`}
    >
      <div className="mb-3 flex w-full">
        <div
          className={`w-2 !bg-[${statusColor[status]}] rounded-s-lg`}
          style={{ backgroundColor: statusColor[status] }}
        />
        <div className="flex w-full items-center justify-between rounded-e-lg bg-white px-5 py-4 dark:bg-dark-secondary">
          <h3 className="flex items-center text-lg font-semibold dark:text-white">
            {status}{" "}
            <span
              className="ml-2 inline-block rounded-full bg-gray-200 p-1 text-center text-sm leading-none dark:bg-dark-tertiary"
              style={{ width: "1.5rem", height: "1.5rem" }}
            >
              {tasksCount}
            </span>
          </h3>
          <div className="flex items-center gap-1">
            <button className="flex h-6 w-5 items-center justify-center dark:text-neutral-500">
              <EllipsisVertical size={26} />
            </button>
            <button
              className="flex h-6 w-6 items-center justify-center rounded bg-gray-200 dark:bg-dark-tertiary dark:text-white"
              onClick={() => setIsModelNewTasOpen(true)}
            >
              <Plus size={16} />
            </button>
          </div>
        </div>
      </div>

      {tasks
        .filter((task) => task.status === status)
        .map((task) => (
          <Task key={task.id} task={task} />
        ))}
    </div>
  );
}
export default TaskColumn;


================================================
FILE: production-level-application/components/global/timeline-view/index.tsx
================================================
import { useAppSelector } from "@/components/wrapper/redux";
import { useGetTasksQuery } from "@/state/api";
import { DisplayOption, Gantt, ViewMode } from "gantt-task-react";
import "gantt-task-react/dist/index.css";
import React, { useMemo, useState } from "react";
import { Spinner } from "../loader/spinner";

type Props = {
  id: string;
  setIsModelNewTasOpen: (isOpen: boolean) => void;
};

type TaskTypeItems = "task" | "milestone" | "project";

function Timeline({ id, setIsModelNewTasOpen }: Props) {
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId: id });

  const [displayOptions, setDisplayOptions] = useState<DisplayOption>({
    viewMode: ViewMode.Month,
    locale: "en-US",
  });

  const ganttTasks = useMemo(() => {
    return (
      tasks?.map((task) => ({
        start: new Date(task.startDate as string),
        end: new Date(task.dueDate as string),
        name: task.title,
        id: `Task-${task.id}`,
        type: "task" as TaskTypeItems,
        progress: task.points ? (task.points / 100) * 100 : 0,
        isDisabled: false,
      })) || []
    );
  }, [tasks]);

  const handleViewModeChange = (
    event: React.ChangeEvent<HTMLSelectElement>
  ) => {
    setDisplayOptions((prevOptions) => ({
      ...prevOptions,
      viewMode: event.target.value as ViewMode,
    }));
  };

  if (isLoading) return <Spinner />;
  if (error) return <div>An error has occurred</div>;

  return (
    <div className="px-4 xl:px-6">
      <div className="flex flex-wrap items-center justify-between gap-2 py-5">
        <h1 className="me-2 text-lg font-bold dark:text-white">
          Project Tasks Timeline
        </h1>
        <div className="relative inline-block w-64">
          <select
            className="focus:shadow-outline block w-full appearance-none rounded border border-gray-400 bg-white px-4 py-2 pr-8 leading-tight shadow hover:border-gray-500 focus:outline-none dark:border-dark-secondary dark:bg-dark-secondary dark:text-white"
            value={displayOptions.viewMode}
            onChange={handleViewModeChange}
          >
            <option value={ViewMode.Day}>Day</option>
            <option value={ViewMode.Week}>Week</option>
            <option value={ViewMode.Month}>Month</option>
          </select>
        </div>
      </div>

      <div className="overflow-hidden rounded-md bg-white shadow dark:bg-dark-secondary dark:text-white">
        <div className="timeline">
          <Gantt
            tasks={ganttTasks}
            {...displayOptions}
            columnWidth={displayOptions.viewMode === ViewMode.Month ? 150 : 100}
            listCellWidth="100px"
            barBackgroundColor={isDarkMode ? "#101214" : "#aeb8c2"}
            barBackgroundSelectedColor={isDarkMode ? "#000" : "#9ba1a6"}
          />
        </div>
        <div className="px-4 pb-5 pt-1">
          <button
            className="flex items-center rounded bg-blue-primary px-3 py-2 text-white hover:bg-blue-600"
            onClick={() => setIsModelNewTasOpen(true)}
          >
            Add New Task
          </button>
        </div>
      </div>
    </div>
  );
}

export default Timeline;


================================================
FILE: production-level-application/components/header/index.tsx
================================================
import React from "react";

type Props = {
  name: string;
  buttonComponent?: any;
  isSmallText?: boolean;
};

function Header({ name, buttonComponent, isSmallText }: Props) {
  return (
    <div className="mb-5 flex w-full items-center justify-between">
      <h1
        className={`${
          isSmallText ? "text-lg" : "text-2xl"
        } font-semibold dark:text-white`}
      >
        {name}
      </h1>
      {buttonComponent}
    </div>
  );
}

export default Header;


================================================
FILE: production-level-application/components/home-page/index.tsx
================================================
/* eslint-disable @next/next/no-img-element */
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetProjectsQuery, useGetTasksQuery } from "@/state/api";
import { Priority, ProjectTypes, TasksTypes } from "@/types/type";
import { DataGrid } from "@mui/x-data-grid";
import { useState } from "react";
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { COLORS, taskColumns } from "../data/columns";
import { Spinner } from "../global/loader/spinner";
import Header from "../header";
import { useAppSelector } from "../wrapper/redux";

type Props = {
  projectId?: number;
  project: ProjectTypes[];
};

function HomePage({ projectId, project }: Props) {
  const [selectProjectId, setSelectProjectId] = useState(projectId);
  const {
    data: tasks,
    isLoading: tasksLoading,
    isError: tasksError,
  } = useGetTasksQuery({
    projectId: String(selectProjectId),
  });

  const { data: projects, isLoading: isProjectsLoading } =
    useGetProjectsQuery();
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  if (tasksLoading || isProjectsLoading) return <Spinner />;
  if (tasksError || !tasks || !projects)
    return <div>An error has occurred</div>;

  const priorityCount = tasks.reduce(
    (acc: Record<string, number>, task: TasksTypes) => {
      const { priority } = task;
      acc[priority as Priority] = (acc[priority as Priority] || 0) + 1;
      return acc;
    },
    {}
  );

  const taskDistribution = Object.keys(priorityCount).map((key) => ({
    name: key,
    count: priorityCount[key],
  }));

  const statusCount = tasks.reduce(
    (acc: Record<string, number>, task: TasksTypes) => {
      const { status } = task;
      acc[status as any] = (acc[status as any] || 0) + 1;
      return acc;
    },
    {}
  );

  const projectStatus = Object.keys(statusCount).map((key) => ({
    name: key,
    count: statusCount[key],
  }));

  const chartColors = isDarkMode
    ? {
        bar: "#8884d8",
        barGrid: "#303030",
        pieFill: "#4A90E2",
        text: "#FFFFFF",
      }
    : {
        bar: "#8884d8",
        barGrid: "#E0E0E0",
        pieFill: "#82ca9d",
        text: "#000000",
      };

  const selectStyles =
    "mb-4 block w-full rounded border border-gray-300 px-3 py-2 dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  return (
    <>
      {tasks.length > 0 ? (
        <div className="h-screen w-screen bg-gray-100 bg-transparent p-8">
          <Header name="Project Management Dashboard" />
          <div>
            <select
              className={selectStyles}
              value={selectProjectId}
              onChange={(e) => setSelectProjectId(e.target.value as any)}
            >
              {project.map((project) => (
                <option key={project.id} value={project.id}>
                  {project.name.toUpperCase()}
                </option>
              ))}
            </select>
          </div>
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary">
              <h3 className="mb-4 text-lg font-semibold dark:text-white">
                Task Priority Distribution
              </h3>
              <ResponsiveContainer width="100%" height={300}>
                <BarChart data={taskDistribution}>
                  <CartesianGrid
                    strokeDasharray="3 3"
                    stroke={chartColors.barGrid}
                  />
                  <XAxis dataKey="name" stroke={chartColors.text} />
                  <YAxis stroke={chartColors.text} />
                  <Tooltip
                    contentStyle={{
                      width: "min-content",
                      height: "min-content",
                    }}
                  />
                  <Legend />
                  <Bar dataKey="count" fill={chartColors.bar} />
                </BarChart>
              </ResponsiveContainer>
            </div>
            <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary">
              <h3 className="mb-4 text-lg font-semibold dark:text-white">
                Project Status
              </h3>
              <ResponsiveContainer width="100%" height={300}>
                <PieChart>
                  <Pie
                    dataKey="count"
                    data={projectStatus}
                    fill="#82ca9d"
                    label
                  >
                    {projectStatus.map((entry, index) => (
                      <Cell
                        key={`cell-${index}`}
                        fill={COLORS[index % COLORS.length]}
                      />
                    ))}
                  </Pie>
                  <Tooltip />
                  <Legend />
                </PieChart>
              </ResponsiveContainer>
            </div>
            <div className="rounded-lg bg-white p-4 shadow dark:bg-dark-secondary md:col-span-2">
              <h3 className="mb-4 text-lg font-semibold dark:text-white">
                Your Tasks
              </h3>
              <div style={{ height: 400, width: "100%" }}>
                <DataGrid
                  rows={tasks}
                  columns={taskColumns}
                  checkboxSelection
                  loading={tasksLoading}
                  getRowClassName={() => "data-grid-row"}
                  getCellClassName={() => "data-grid-cell"}
                  className={dataGridClassNames}
                  sx={dataGridSxStyles(isDarkMode)}
                />
              </div>
            </div>
          </div>
        </div>
      ) : (
        <div className="w-screen h-screen flex flex-col justify-center items-center">
          {project.length > 0 && (
            <div className="w-96">
              <select
                className={selectStyles}
                value={selectProjectId}
                onChange={(e) => setSelectProjectId(e.target.value as any)}
              >
                {project.map((project) => (
                  <option key={project.id} value={project.id}>
                    {project.name.toUpperCase()}
                  </option>
                ))}
              </select>
            </div>
          )}
          <img
            src="https://projectvectors.com.au/_next/image?url=%2Fimages%2Fmanagement.png&w=1080&q=75"
            alt="img"
            className="w-[500px]"
          />
          <p className="text-black dark:text-white text-lg font-semibold mt-4">
            {`Currently You Don't have Task`}
          </p>
        </div>
      )}
    </>
  );
}
export default HomePage;


================================================
FILE: production-level-application/components/home-page/root-home-page/index.tsx
================================================
/* eslint-disable @next/next/no-img-element */
"use client";

import ModalNewProject from "@/components/modal/modal-new-project";
import { useCreateUserMutation, useGetProjectsQuery } from "@/state/api";
import { useUser } from "@clerk/nextjs";
import { PlusSquare } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import HomePage from "..";

type Props = {};

function RootHomePage({}: Props) {
  const { isSignedIn, user } = useUser();
  const [createUser] = useCreateUserMutation();
  const { data: projects, isLoading: isProjectsLoading } =
    useGetProjectsQuery();
  const [isModalNameProjectOpen, setIsModalNameProjectOpen] = useState(false);

  const createCurrentUser = useMemo(
    () => async () => {
      if (user?.id) {
        await createUser({
          firstName: user.firstName! || user.username!,
          secondName: user.lastName! || "",
          profilePictureUrl: user.firstName
            ? user.imageUrl
            : `https://api.dicebear.com/9.x/initials/png?seed=${user.username}`,
          clerkId: user.id,
        });
      }
    },
    [
      createUser,
      user?.firstName,
      user?.id,
      user?.imageUrl,
      user?.lastName,
      user?.username,
    ]
  );

  useEffect(() => {
    createCurrentUser();
  }, [createCurrentUser, user?.id]);

  return (
    <div>
      {projects && projects.length > 0 ? (
        <HomePage projectId={projects[0].id} project={projects} />
      ) : (
        <div className="w-screen h-screen flex flex-col justify-center items-center">
          <img
            src="https://projectvectors.com.au/_next/image?url=%2Fimages%2Fmanagement.png&w=1080&q=75"
            alt="img"
            className="w-[500px]"
          />
          <p className="text-black dark:text-white text-lg font-semibold mt-4">
            {`Currently You Don't have Project`}
          </p>
          <div className="flex justify-center mt-4 gap-x-2">
            <ModalNewProject
              isOpen={isModalNameProjectOpen}
              onClose={() => setIsModalNameProjectOpen(false)}
            />
            <button
              className="flex items-center rounded-md bg-blue-primary px-3 py-2 text-white hover:bg-blue-600 w-full"
              onClick={() => setIsModalNameProjectOpen(true)}
            >
              <PlusSquare className="mr-1 h-5 w-5" /> New Board
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

export default RootHomePage;


================================================
FILE: production-level-application/components/modal/index.tsx
================================================
import { X } from "lucide-react";
import React from "react";
import ReactDOM from "react-dom";
import ClientOnly from "../global/client-only";
import Header from "../header";

type Props = {
  children: React.ReactNode;
  isOpen: boolean;
  onClose: () => void;
  name: string;
};

function Modal({ children, isOpen, onClose, name }: Props) {
  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div className="fixed inset-0 z-50 flex h-full w-full items-center justify-center overflow-y-auto bg-gray-600 bg-opacity-50 p-4">
      <ClientOnly>
        <div className="w-screen max-w-2xl rounded-lg bg-white p-4 shadow-lg dark:bg-dark-secondary">
          <Header
            name={name}
            buttonComponent={
              <button
                className="flex h-7 w-7 items-center justify-center rounded-full bg-blue-primary text-white hover:bg-blue-600"
                onClick={onClose}
              >
                <X size={18} />
              </button>
            }
            isSmallText
          />
          {children}
        </div>
      </ClientOnly>
    </div>,

    document.body
  );
}

export default Modal;


================================================
FILE: production-level-application/components/modal/modal-new-project/index.tsx
================================================
import { ButtonLoader } from "@/components/global/loader/buttonLoader";
import { useCreateProjectMutation } from "@/state/api";
import { useUser } from "@clerk/nextjs";
import { formatISO } from "date-fns";
import { useState } from "react";
import { toast } from "react-toastify";
import Modal from "..";

type Props = {
  isOpen: boolean;
  onClose: () => void;
};

function ModalNewProject({ isOpen, onClose }: Props) {
  const { isSignedIn, user, isLoaded } = useUser();
  const [createProject, { isLoading }] = useCreateProjectMutation();
  const [projectName, setProjectName] = useState("");
  const [description, setDescription] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");

  const handleSubmit = async () => {
    if (!projectName || !startDate || !endDate) return;

    const formateStartDate = formatISO(new Date(startDate), {
      representation: "complete",
    });
    const formateEndDate = formatISO(new Date(endDate), {
      representation: "complete",
    });

    await createProject({
      user: user?.id,
      name: projectName,
      description,
      startDate: formateStartDate,
      endDate: formateEndDate,
    })
      .then(() =>
        toast.success("Project Created Successfully!", {
          position: "bottom-right",
        })
      )
      .catch(() =>
        toast.error("Project Created Error", { position: "bottom-right" })
      );

    onClose();
  };

  const isFormValid = () => {
    return projectName && description && startDate && endDate;
  };

  const inputStyle =
    "w-full rounded-md border border-gray-300 p-2 shadow-sm dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  return (
    <Modal isOpen={isOpen} onClose={onClose} name="Create New Project">
      <form
        className="mt-4 space-y-6"
        onSubmit={(e) => {
          e.preventDefault();
          handleSubmit();
        }}
      >
        <input
          type="text"
          className={inputStyle}
          placeholder="Project Name"
          value={projectName}
          onChange={(e) => setProjectName(e.target.value)}
        />
        <textarea
          className={inputStyle}
          placeholder="Description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <input
            type="date"
            className={inputStyle}
            value={startDate}
            onChange={(e) => setStartDate(e.target.value)}
          />
          <input
            type="date"
            className={inputStyle}
            value={endDate}
            onChange={(e) => setEndDate(e.target.value)}
          />
        </div>
        <button
          type="submit"
          className={`focus-offset-2 mt-4 flex w-full justify-center rounded-md border border-transparent bg-blue-primary px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-600 ${
            !isFormValid() || isLoading ? "cursor-not-allowed opacity-50" : ""
          }`}
          disabled={!isFormValid() || isLoading}
        >
          {isLoading ? <ButtonLoader /> : "Create Project"}
        </button>
      </form>
    </Modal>
  );
}

export default ModalNewProject;


================================================
FILE: production-level-application/components/modal/model-new-task/index.tsx
================================================
import ImageUpload from "@/components/global/image-upload";
import { ButtonLoader } from "@/components/global/loader/buttonLoader";
import {
  useCreateTasksMutation,
  useGetUserQuery,
  useLazyGetTasksQuery,
} from "@/state/api";
import { Priority, Status } from "@/types/type";
import { formatISO } from "date-fns";
import { useState } from "react";
import { toast } from "react-toastify";
import Modal from "..";

type Props = {
  id?: string | null;
  userId?: string;
  isOpen: boolean;
  onClose: () => void;
};

function ModelNewTask({ id, userId, isOpen, onClose }: Props) {
  const { data: user, error } = useGetUserQuery({
    userId: userId ?? "defaultUserId",
  });
  const [createTask, { isLoading }] = useCreateTasksMutation();
  const [refetchTasks] = useLazyGetTasksQuery();
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [status, setStatus] = useState<Status>(Status.ToDo);
  const [priority, setPriority] = useState<Priority>(Priority.Backlog);
  const [tags, setTags] = useState("");
  const [startDate, setStartDate] = useState("");
  const [dueDate, setDueDate] = useState("");
  const [projectId, setProjectId] = useState("");
  const [imageSrc, setImageSrc] = useState({
    secure_url: "",
  });

  const handleSubmit = async () => {
    if (!title || !(id !== null || projectId)) return;

    const formateStartDate = formatISO(new Date(startDate), {
      representation: "complete",
    });
    const formateEndDate = formatISO(new Date(dueDate), {
      representation: "complete",
    });

    await createTask({
      title,
      description,
      status,
      priority,
      tags,
      startDate: formateStartDate,
      dueDate: formateEndDate,
      authorUserId: /* user?.id */ userId,
      projectId: id !== null ? id : projectId,
      imageSrc: imageSrc.secure_url,
      userId: user?.id,
    })
      .then(() =>
        toast.success("Task Created Successfully!", {
          position: "bottom-right",
        })
      )
      .catch(() =>
        toast.error("Task Created Error", { position: "bottom-right" })
      );
    refetchTasks({ projectId: String(id) });

    setTitle("");
    setDescription("");
    setStatus(Status.ToDo);
    setPriority(Priority.Backlog);
    setTags("");
    setStartDate("");
    setDueDate("");
    setProjectId("");
    setImageSrc({
      secure_url: "",
    });

    onClose();
  };

  const isFormValid = () => {
    return title && (id !== null || projectId) && startDate && dueDate;
  };

  const selectStyles =
    "mb-4 block w-full rounded border border-gray-300 px-3 py-2 dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  const inputStyle =
    "w-full rounded-md border border-gray-300 p-2 shadow-sm dark:border-dark-tertiary dark:bg-dark-tertiary dark:text-white dark:focus:outline-none";

  return (
    <Modal isOpen={isOpen} onClose={onClose} name="Create New Task">
      <form
        className="mt-4 space-y-6"
        onSubmit={(e) => {
          e.preventDefault();
          handleSubmit();
        }}
      >
        <input
          type="text"
          className={inputStyle}
          placeholder="Title"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <textarea
          className={inputStyle}
          placeholder="Description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <select
            className={selectStyles}
            value={status}
            onChange={(e) => setStatus(e.target.value as any)}
          >
            <option value="">Select Status</option>
            <option value={Status.ToDo}>To Do</option>
            <option value={Status.WorkInProgress}>Work In Progress</option>
            <option value={Status.UnderReview}>Under Review</option>
            <option value={Status.Completed}>Completed</option>
          </select>
          <select
            className={selectStyles}
            value={priority}
            onChange={(e) =>
              setPriority(Priority[e.target.value as keyof typeof Priority])
            }
          >
            <option value="">Select Priority</option>
            <option value={Priority.Urgent}>Urgent</option>
            <option value={Priority.High}>High</option>
            <option value={Priority.Medium}>Medium</option>
            <option value={Priority.Low}>Low</option>
            <option value={Priority.Backlog}>Backlog</option>
          </select>
        </div>
        <input
          type="text"
          className={inputStyle}
          placeholder="Tags (comma separated)"
          value={tags}
          onChange={(e) => setTags(e.target.value)}
        />
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-2">
          <input
            type="date"
            className={inputStyle}
            value={startDate}
            onChange={(e) => setStartDate(e.target.value)}
          />
          <input
            type="date"
            className={inputStyle}
            value={dueDate}
            onChange={(e) => setDueDate(e.target.value)}
          />
        </div>
        <div className="flex flex-col gap-y-4">
          <p className="font-semibold text-center text-[15px] text-black dark:text-gray-400">
            Add Attachment
          </p>
          <ImageUpload setImageSrc={setImageSrc} value={imageSrc.secure_url} />
        </div>

        {/*         <input
          type="text"
          className={inputStyle}
          placeholder="Author User ID"
          value={authorUserId}
          onChange={(e) => setAuthorUserId(e.target.value)}
        />
        <input
          type="text"
          className={inputStyle}
          placeholder="Assigned User ID"
          value={assignedUserId}
          onChange={(e) => setAssignedUserId(e.target.value)}
        /> */}
        {id === undefined && (
          <input
            type="text"
            className={inputStyle}
            placeholder="Project Id"
            value={projectId}
            onChange={(e) => setProjectId(e.target.value)}
          />
        )}
        <button
          type="submit"
          className={`focus-offset-2 mt-4 flex w-full justify-center rounded-md border border-transparent bg-blue-primary px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-600 ${
            !isFormValid() || isLoading ? "cursor-not-allowed opacity-50" : ""
          }`}
          disabled={!isFormValid() || isLoading}
        >
          {isLoading ? <ButtonLoader /> : "Create Task"}
        </button>
      </form>
    </Modal>
  );
}

export default ModelNewTask;


================================================
FILE: production-level-application/components/modal/model-share-project/index.tsx
================================================
import { useState } from "react";
import Modal from "..";
import { useUpdateProjectAuthorsMutation } from "@/state/api";
import { toast } from "react-toastify";

type Props = {
  id: string;
  currentUserId: string;
  isOpen: boolean;
  onClose: () => void;
  sharedProjectId: string;
  setSharedProjectId: (sharedProjectId: string) => void;
};

function ModelShareModel({
  isOpen,
  onClose,
  id,
  currentUserId,
  setSharedProjectId,
  sharedProjectId,
}: Props) {
  const [updateProjectAuthors, { error: updateError }] =
    useUpdateProjectAuthorsMutation();
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(id);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000); // Reset after 2 seconds
    } catch (err) {
      console.error("Failed to copy:", err);
    }
  };

  const handleUpdateAuthors = async (authorIds: string, sProjectId: string) => {
    if (!authorIds) return;
    if (!sProjectId) return;

    try {
      await updateProjectAuthors({
        projectId: sProjectId,
        userId: authorIds,
      })
        .then(() => {
          if (
            updateError &&
            "status" in updateError &&
            updateError.status === 401
          ) {
            toast.error(
              "Your Already In Project Or Current Project Not available!",
              {
                position: "bottom-right",
              }
            );
          } else if (
            updateError &&
            "status" in updateError &&
            updateError.status === 400
          ) {
            toast.error("Missing projectId", {
              position: "bottom-right",
            });
          } else {
            toast.success("Project Join Successfully!", {
              position: "bottom-right",
            });

            setSharedProjectId("");
            onClose();
          }
        })
        .catch(() =>
          toast.error("Project Join Error", { position: "bottom-right" })
        );
    } catch (error: any) {
      console.log("🚀 ~ handleUpdateAuthors ~ error:", error);
    }
  };

  return (
    <Modal isOpen={isOpen} onClose={onClose} name="Collaborate With Others">
      <div className="flex flex-col gap-y-3">
        <div className="flex flex-col justify-start items-start">
          <p className="text-black dark:text-white p-2">Copy Id and Share</p>
          <div className="flex items-center space-x-4 p-4 border dark:border-dark-tertiary rounded-lg bg-gray-100 dark:bg-dark-secondary shadow-md w-full">
            <input
              type="text"
              value={id}
              readOnly
              className="w-full p-2 text-gray-700 dark:text-white border dark:border-gray-500 rounded-md bg-gray-200 dark:bg-dark-tertiary cursor-pointer"
            />
            <button
              onClick={handleCopy}
              className="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700 transition-all"
            >
              {copied ? "Copied!" : "Copy"}
            </button>
          </div>
        </div>
        <div className="flex flex-col justify-start items-start">
          <p className="text-black dark:text-white p-2">{`For Join Other Member's Enter Shared Id`}</p>
          <div className="flex items-center space-x-4 p-4 border dark:border-dark-tertiary rounded-lg bg-gray-100 dark:bg-dark-secondary shadow-md w-full">
            <input
              type="text"
              value={sharedProjectId}
              onChange={(e) => setSharedProjectId(e.target.value)}
              placeholder="Enter Shared Id"
              className="w-full p-2 text-gray-700 dark:text-white border dark:border-gray-500 rounded-md bg-gray-200 dark:bg-dark-tertiary"
            />
            <button
              className="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700 transition-all"
              onClick={() =>
                handleUpdateAuthors(currentUserId, sharedProjectId)
              }
            >
              Enter
            </button>
          </div>
        </div>
      </div>
    </Modal>
  );
}

export default ModelShareModel;


================================================
FILE: production-level-application/components/navbar/home/index.tsx
================================================
"use client";

import ImageCard from "@/components/global/image-card";
import { useAppDispatch, useAppSelector } from "@/components/wrapper/redux";
import { setIsDarkMode } from "@/state";
import { Moon, Sun } from "lucide-react";
import Link from "next/link";
import React from "react";

type Props = {};

const imageData = [
  {
    src: "https://www.itarian.com/assets-new/images/project-management.png",
    aspectRatio: "0.94",
  },
  {
    src: "https://png.pngtree.com/png-vector/20220527/ourmid/pngtree-woman-doing-project-management-png-image_4752006.png",
    aspectRatio: "0.94",
    marginTop: "mt-4",
  },
  /*   {
    src: "https://marketplace.canva.com/EAE2pXyqyx0/1/0/1600w/canva-simple-instagram-frame-template-instagram-post-ObQSn5BL2ZQ.jpg",
    aspectRatio: "1.7",
    marginTop: "mt-4",
  }, */
];

const imageData2 = [
  {
    src: "https://cdni.iconscout.com/illustration/premium/thumb/online-test-illustration-download-in-svg-png-gif-file-formats--exam-education-e-learning-digital-world-pack-seo-web-illustrations-6770271.png?f=webp",
    aspectRatio: "1.7",
  },
  {
    src: "https://static.vecteezy.com/system/resources/previews/022/608/528/non_2x/business-infographic-analysis-marketing-data-analysis-marketing-business-solutions-free-png.png",
    aspectRatio: "0.94",
    marginTop: "mt-4",
  },
  {
    src: "https://cdni.iconscout.com/illustration/premium/thumb/project-planning-illustration-download-in-svg-png-gif-file-formats--management-plan-business-discussion-teamwork-pack-illustrations-6666400.png?f=webp",
    aspectRatio: "0.94",
    marginTop: "mt-4",
  },
];

function HomeNavBar({}: Props) {
  const dispatch = useAppDispatch();
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  return (
    <section
      className={`relative h-screen ${isDarkMode ? "bg-black" : "bg-white"}`}
    >
      {isDarkMode && (
        <div className="absolute inset-0 bg-[linear-gradient(to_right,#0f172a_1px,transparent_1px),linear-gradient(to_bottom,#0f172a_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_110%)]" />
      )}
      <div className="relative">
        <div className="flex items-center justify-between">
          <div className="flex flex-col w-full max-md:ml-0 max-md:w-full">
            <div className="flex overflow-hidden flex-col w-full max-md:mt-10 max-md:max-w-full">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2 mt-4">
                  {/*  <div className="h-8 w-8 rounded-lg bg-white text-black flex items-center justify-center font-bold">
                    li
                  </div> */}
                  <span
                    className={`pl-4 text-xl font-semibold ${
                      isDarkMode ? "text-blue-200" : "text-blue-800"
                    }`}
                  >
                    Project Management
                  </span>
                </div>
                <nav
                  className={`hidden space-x-6 text-sm md:block  ${
                    isDarkMode ? "text-blue-200" : "text-blue-800"
                  }`}
                >
                  <Link href="#features">Features</Link>
                  <Link href="#pricing">Pricing</Link>
                  <Link href="#about">About</Link>
                </nav>
                <div className="flex justify-center items-center gap-x-2">
                  <button
                    onClick={() => dispatch(setIsDarkMode(!isDarkMode))}
                    className={
                      isDarkMode
                        ? `rounded p-2 hover:bg-gray-700`
                        : `rounded p-2 hover:bg-gray-100`
                    }
                  >
                    {isDarkMode ? (
                      <Sun className="h-6 w-6 cursor-pointer text-white" />
                    ) : (
                      <Moon className="h-6 w-6 cursor-pointer text-black" />
                    )}
                  </button>

                  <Link href="/dashboard">
                    <button className="bg-white text-black font-semibold rounded-md px-6 py-4">
                      Login
                    </button>
                  </Link>
                </div>
              </div>
              {/* Rest of the component implementation follows with the extracted components */}
              {/* Features section */}

              <div className="flex overflow-hidden flex-col px-16 mt-28 w-full min-h-[900px] max-md:px-5 max-md:max-w-full">
                <div className="flex flex-wrap flex-1 size-full max-md:max-w-full">
                  <div className="flex flex-col flex-1 shrink justify-center pr-20 basis-0 min-w-[240px] max-md:max-w-full">
                    <div className="flex flex-col w-full text-white max-md:max-w-full">
                      <h1
                        className={`text-4xl font-bold leading-tight tracking-tighter  sm:text-5xl md:text-6xl lg:text-7xl ${
                          isDarkMode ? "text-gray-200" : "text-gray-700"
                        }`}
                      >
                        Smart Project Management System for Agile Teams
                      </h1>
                      <p
                        className={`mt-6 text-lg ${
                          isDarkMode ? "text-blue-200" : "text-blue-700"
                        }`}
                      >
                        {`The Smart Project Management System is a comprehensive
                        web-based platform designed to help Agile teams
                        efficiently plan, execute, and monitor projects. The
                        system offers a collaborative workspace where team
                        members can create tasks, assign responsibilities, set
                        deadlines, and track progress using visual tools like
                        Kanban boards and Gantt charts.`}
                      </p>
                    </div>
                    <div className="flex gap-4 items-start self-start mt-8 text-base">
                      <Link href="/dashboard">
                        <button className="bg-blue-600 text-white hover:bg-blue-700 rounded-md px-6 py-4">
                          Get Started
                        </button>
                      </Link>
                      <Link href="/dashboard">
                        <button
                          className={`border-blue-400  hover:bg-blue-900/50 rounded-md px-6 py-4 ${
                            isDarkMode ? "text-white " : "text-gray-700"
                          }`}
                        >
                          Learn More
                        </button>
                      </Link>
                    </div>
                  </div>
                  <div className="flex relative flex-1 shrink gap-4 items-start my-auto basis-20 left-44">
                    <img
                      src="https://projectvectors.com.au/_next/image?url=%2Fimages%2Fmanagement.png&w=1080&q=75"
                      alt="img"
                      className="w-[800px]"
                    />
                    {/*                   <div className="flex absolute right-0 bottom-0 z-0 flex-col h-[800px] left-[550px] min-w-[240px] w-[360px]">
                      {imageData.map((image, index) => (
                        <ImageCard
                          key={`right-${index}`}
                          src={image.src}
                          aspectRatio={image.aspectRatio}
                          marginTop={image.marginTop}
                        />
                      ))}
                    </div>
                    <div className="flex absolute bottom-0 left-[100px] z-0 flex-col h-[1000px] right-[337px] w-[370px]">
                      {imageData2.map((image, index) => (
                        <ImageCard
                          key={`left-${index}`}
                          src={image.src}
                          aspectRatio={image.aspectRatio}
                          marginTop={image.marginTop}
                        />
                      ))}
                    </div> */}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

export default HomeNavBar;


================================================
FILE: production-level-application/components/navbar/index.tsx
================================================
import { setIsDarkMode, setIsSidebarCollapsed } from "@/state";
import { UserButton } from "@clerk/nextjs";
import { Menu, Moon, Search, Settings, Sun } from "lucide-react";
import Link from "next/link";
import { useAppDispatch, useAppSelector } from "../wrapper/redux";

type Props = {};

function Navbar({}: Props) {
  const dispatch = useAppDispatch();
  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed
  );
  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);

  return (
    <div className="flex items-center justify-between bg-white px-4 py-3 dark:bg-black">
      <div className="flex items-center gap-8">
        {!isSidebarCollapsed ? null : (
          <button
            onClick={() => dispatch(setIsSidebarCollapsed(!isSidebarCollapsed))}
          >
            <Menu className="h-8 w-8 dark:text-white" />
          </button>
        )}
        <div className="relative flex h-min w-[200px]">
          <Search className="absolute left-[4px] top-1/2 mr-2 h-5 w-5 -translate-y-1/2 transform cursor-pointer dark:text-white" />
          <input
            className="w-full rounded border-none bg-gray-100 p-2 pl-8 placeholder-gray-500 focus:border-transparent focus:outline-none dark:bg-gray-700 dark:text-white dark:placeholder-white"
            type="search"
            placeholder="Search..."
          />
        </div>
      </div>
      <div className="flex items-center">
        <button
          onClick={() => dispatch(setIsDarkMode(!isDarkMode))}
          className={
            isDarkMode
              ? `rounded p-2 dark:hover:bg-gray-700`
              : `rounded p-2 hover:bg-gray-100`
          }
        >
          {isDarkMode ? (
            <Sun className="h-6 w-6 cursor-pointer dark:text-white" />
          ) : (
            <Moon className="h-6 w-6 cursor-pointer dark:text-white" />
          )}
        </button>
        <Link
          href="/settings"
          className={
            isDarkMode
              ? `h-min w-min rounded p-2 dark:hover:bg-gray-700`
              : `h-min w-min rounded p-2 hover:bg-gray-100`
          }
        >
          <Settings className="h-6 w-6 cursor-pointer dark:text-white" />
        </Link>
        <div className="ml-2 mr-5 hidden min-h-[2em] w-[0.1rem] bg-gray-200 md:inline-block"></div>
        <div className="hidden items-center justify-between md:flex">
          <div className="align-center flex h-9 w-9 justify-center">
            {/* <User className="h-6 w-6 cursor-pointer self-center rounded-full dark:text-white" /> */}
            <UserButton />
          </div>
        </div>
      </div>
    </div>
  );
}

export default Navbar;


================================================
FILE: production-level-application/components/priority-page/index.tsx
================================================
"use client";

import { dataGridClassNames, dataGridSxStyles } from "@/lib/utils";
import { useGetTasksByUserQuery } from "@/state/api";
import { Priority, TasksTypes } from "@/types/type";
import { useUser } from "@clerk/nextjs";
import { DataGrid } from "@mui/x-data-grid";
import { useState } from "react";
import { priorityColumns } from "../data/columns";
import TaskCard from "../global/task-card";
import Header from "../header";
import ModelNewTask from "../modal/model-new-task";
import { useAppSelector } from "../wrapper/redux";

type Props = {
  priority: Priority;
};

function PriorityPage({ priority }: Props) {
  const { isSignedIn, user } = useUser();
  const [view, setView] = useState("list");
  const [isMobileNewTaskOpen, setIsMobileNewTaskOpen] = useState(false);

  const userId = user?.id ?? null;

  const {
    data: task,
    isLoading,
    isError: isTasksError,
  } = useGetTasksByUserQuery(userId as any);

  const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
  const filteredTasks = task?.filter(
    (t: TasksTypes) => t.priority === priority
  );

  if (isTasksError || !task) return <div>An error occurred</div>;

  return (
    <div className="m-5 p-4">
      <ModelNewTask
        isOpen={isMobileNewTaskOpen}
        onClose={() => setIsMobileNewTaskOpen(false)}
      />
      <Header
        name="Priority Page"
        buttonComponent={
          <button
            className="mr-3 rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700"
            onClick={() => setIsMobileNewTaskOpen(true)}
          >
            Add Task
          </button>
        }
      />
      <div className="mb-4 flex justify-start">
        <button
          className={`rounded-bl-md rounded-tl-md px-4 py-2 ${
            view === "list" ? "bg-gray-300" : "bg-white"
          } `}
          onClick={() => setView("list")}
        >
          List
        </button>
        <button
          className={`rounded-br-md rounded-tr-md px-4 py-2 ${
            view === "table" ? "bg-gray-300" : "bg-white"
          } `}
          onClick={() => setView("table")}
        >
          Table
        </button>
      </div>
      {isLoading ? (
        <div>Loading tasks...</div>
      ) : view === "list" ? (
        <div className="grid grid-cols-1 gap-4">
          {filteredTasks?.map((task: TasksTypes) => (
            <TaskCard key={task.id} task={task} />
          ))}
        </div>
      ) : (
        view === "table" &&
        filteredTasks && (
          <div className="z-0 w-full">
            <DataGrid
              rows={filteredTasks}
              columns={priorityColumns}
              checkboxSelection
              getRowId={(row) => row.id}
              className={dataGridClassNames}
              sx={dataGridSxStyles(isDarkMode)}
            />
          </div>
        )
      )}
    </div>
  );
}

export default PriorityPage;


================================================
FILE: production-level-application/components/sidebar/index.tsx
================================================
"use client";

import { setIsSidebarCollapsed } from "@/state";
import { useGetProjectsQuery } from "@/state/api";
import {
  AlertCircle,
  AlertOctagon,
  AlertTriangle,
  Briefcase,
  ChevronDown,
  ChevronUp,
  Home,
  Layers3,
  LockIcon,
  LucideIcon,
  PlusSquare,
  ShieldAlert,
  X,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { useDispatch } from "react-redux";
import ModalNewProject from "../modal/modal-new-project";
import { useAppSelector } from "../wrapper/redux";

type Props = {};

function SideBar({}: Props) {
  const dispatch = useDispatch();
  const [showProject, setShowProject] = useState(true);
  const [showPriority, setShowPriority] = useState(true);
  const [isModalNameProjectOpen, setIsModalNameProjectOpen] = useState(false);

  const { data: projects } = useGetProjectsQuery();

  const isSidebarCollapsed = useAppSelector(
    (state) => state.global.isSidebarCollapsed
  );

  /*   if (!currentUser) return null;
  const currentUserDetails = currentUser.user; */
  const sideBarClassNames = `fixed flex flex-col h-full justify-between shadow-xl
  transition-all duration-300 ease-in-out z-40 dark:bg-black overflow-y-auto bg-white
  ${
    isSidebarCollapsed
      ? "max-w-0 overflow-hidden opacity-0"
      : "max-w-64 opacity-100"
  }`;

  return (
    <div className={sideBarClassNames}>
      <div className="flex h-[100%] w-full flex-col justify-start">
        {/*    */}
        <div className="z-50 flex min-h-[56px] w-64 items-center justify-between bg-white px-6 pt-3 dark:bg-black">
          <div className="text-xl font-bold text-gray-800 dark:text-white">
            LIST
          </div>
          {isSidebarCollapsed ? null : (
            <button
              className="py-3"
              onClick={() =>
                dispatch(setIsSidebarCollapsed(!isSidebarCollapsed))
              }
            >
              <X className="h-6 w-6 text-gray-800 hover:text-gray-500 dark:text-white" />
            </button>
          )}
        </div>
        <div className="flex items-center gap-5 border-y-[1.5px] border-gray-500 px-8 py-4 dark:border-gray-700">
          <Image src="/logo.png" alt="logo" width={40} height={40} />
          <div>
            <h3 className="text-lg font-bold tracking-wide dark:text-gray-200">
              Project Management
            </h3>

            <div className="mt-1 flex items-start gap-2">
              <LockIcon className="mt-[0.1rem] h-3 w-3 text-gray-500 dark:text-gray-400" />
              <p className="text-xs text-gray-500">Private</p>
            </div>
          </div>
        </div>
        <nav className="z-10 w-full">
          <SidebarLink icon={Home} label="Home" href="/dashboard" />
          {projects && projects.length > 0 && (
            <SidebarLink
              icon={Briefcase}
              label="Timeline"
              href="/dashboard/timeline"
            />
          )}

          {/*           <SidebarLink icon={Search} label="Search" href="/dashboard/search" />
          <SidebarLink
            icon={Settings}
            label="Settings"
            href="/dashboard/settings"
          />
          <SidebarLink icon={User} label="Users" href="/dashboard/users" />
          <SidebarLink icon={Users} label="Teams" href="/dashboard/teams" /> */}
        </nav>
        <button
          onClick={() => setShowProject((prev) => !prev)}
          className="flex w-full items-center justify-between px-8 py-3 text-gray-500"
        >
          <span>Projects</span>
          {showProject ? (
            <ChevronUp className="h-5 w-5" />
          ) : (
            <ChevronDown className="h-5 w-5" />
          )}
        </button>
        {showProject &&
          projects?.map((project) => (
            <SidebarLink
              key={project.id}
              icon={Briefcase}
              label={project.name}
              href={`/dashboard/projects/${project.id}`}
            />
          ))}
        <button
          onClick={() => setShowPriority((prev) => !prev)}
          className="flex w-full items-center justify-between px-8 py-3 text-gray-500"
        >
          <span>Priory</span>
          {showPriority ? (
            <ChevronUp className="h-5 w-5" />
          ) : (
            <ChevronDown className="h-5 w-5" />
          )}
        </button>
        {showPriority && (
          <>
            <SidebarLink
              icon={AlertCircle}
              label="Urgent"
              href="/dashboard/priority/urgent"
            />
            <SidebarLink
              icon={ShieldAlert}
              label="High"
              href="/dashboard/priority/high"
            />
            <SidebarLink
              icon={AlertTriangle}
              label="Medium"
              href="/dashboard/priority/medium"
            />
            <SidebarLink
              icon={AlertOctagon}
              label="Low"
              href="/dashboard/priority/low"
            />
            
Download .txt
gitextract__q2wgi47/

├── README.md
├── aws-bucket-policy.json
├── client/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierrc
│   ├── README.md
│   ├── app/
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   ├── loading.tsx
│   │   ├── page.tsx
│   │   ├── priority/
│   │   │   ├── backlog/
│   │   │   │   └── page.tsx
│   │   │   ├── high/
│   │   │   │   └── page.tsx
│   │   │   ├── low/
│   │   │   │   └── page.tsx
│   │   │   ├── medium/
│   │   │   │   └── page.tsx
│   │   │   └── urgent/
│   │   │       └── page.tsx
│   │   ├── projects/
│   │   │   └── [id]/
│   │   │       └── page.tsx
│   │   ├── search/
│   │   │   └── page.tsx
│   │   ├── settings/
│   │   │   └── page.tsx
│   │   ├── teams/
│   │   │   └── page.tsx
│   │   ├── timeline/
│   │   │   └── page.tsx
│   │   └── users/
│   │       └── page.tsx
│   ├── components/
│   │   ├── Header/
│   │   │   └── index.tsx
│   │   ├── data/
│   │   │   └── columns.tsx
│   │   ├── global/
│   │   │   ├── auth-provider/
│   │   │   │   └── index.tsx
│   │   │   ├── border-view/
│   │   │   │   └── index.tsx
│   │   │   ├── loader/
│   │   │   │   └── spinner.tsx
│   │   │   ├── project-header/
│   │   │   │   └── index.tsx
│   │   │   ├── tab-button/
│   │   │   │   └── index.tsx
│   │   │   ├── task/
│   │   │   │   └── index.tsx
│   │   │   ├── task-card/
│   │   │   │   └── index.tsx
│   │   │   └── task-column/
│   │   │       └── index.tsx
│   │   ├── home-page/
│   │   │   └── index.tsx
│   │   ├── list-view/
│   │   │   └── index.tsx
│   │   ├── modal/
│   │   │   ├── index.tsx
│   │   │   ├── modal-new-project/
│   │   │   │   └── index.tsx
│   │   │   └── model-new-task/
│   │   │       └── index.tsx
│   │   ├── navbar/
│   │   │   └── index.tsx
│   │   ├── priorityPage/
│   │   │   └── index.tsx
│   │   ├── project-card/
│   │   │   └── index.tsx
│   │   ├── project-page/
│   │   │   └── index.tsx
│   │   ├── search-page/
│   │   │   └── index.tsx
│   │   ├── settings-page/
│   │   │   └── index.tsx
│   │   ├── sidebar/
│   │   │   └── index.tsx
│   │   ├── table-view/
│   │   │   └── index.tsx
│   │   ├── team-page/
│   │   │   └── index.tsx
│   │   ├── timeline/
│   │   │   └── index.tsx
│   │   ├── timeline-view/
│   │   │   └── index.tsx
│   │   ├── user-card/
│   │   │   └── index.tsx
│   │   ├── user-page/
│   │   │   └── index.tsx
│   │   └── wrapper/
│   │       ├── dashboardWrapper.tsx
│   │       └── redux.tsx
│   ├── lib/
│   │   └── utils.ts
│   ├── next.config.mjs
│   ├── package.json
│   ├── postcss.config.mjs
│   ├── state/
│   │   ├── api.ts
│   │   └── index.ts
│   ├── tailwind.config.ts
│   ├── tsconfig.json
│   └── types/
│       └── type.ts
├── lamda_trigger.mjs
├── production-level-application/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── README.md
│   ├── actions/
│   │   └── index.ts
│   ├── app/
│   │   ├── (auth)/
│   │   │   ├── layout.tsx
│   │   │   ├── sign-in/
│   │   │   │   └── [[...sign-in]]/
│   │   │   │       └── page.tsx
│   │   │   └── sign-up/
│   │   │       └── [[...sign-up]]/
│   │   │           └── page.tsx
│   │   ├── api/
│   │   │   ├── move/
│   │   │   │   └── [taskId]/
│   │   │   │       └── route.tsx
│   │   │   ├── projects/
│   │   │   │   ├── [projectId]/
│   │   │   │   │   └── route.ts
│   │   │   │   └── route.ts
│   │   │   ├── tasks/
│   │   │   │   ├── [projectId]/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── route.ts
│   │   │   │   └── user/
│   │   │   │       └── [userId]/
│   │   │   │           └── route.ts
│   │   │   └── user/
│   │   │       ├── [userId]/
│   │   │       │   └── route.ts
│   │   │       └── route.ts
│   │   ├── dashboard/
│   │   │   ├── layout.tsx
│   │   │   ├── loading.tsx
│   │   │   ├── page.tsx
│   │   │   ├── priority/
│   │   │   │   ├── backlog/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── high/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── low/
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── medium/
│   │   │   │   │   └── page.tsx
│   │   │   │   └── urgent/
│   │   │   │       └── page.tsx
│   │   │   ├── projects/
│   │   │   │   └── [id]/
│   │   │   │       └── page.tsx
│   │   │   └── timeline/
│   │   │       └── page.tsx
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   ├── loading.tsx
│   │   └── page.tsx
│   ├── components/
│   │   ├── data/
│   │   │   └── columns.tsx
│   │   ├── global/
│   │   │   ├── border-view/
│   │   │   │   └── index.tsx
│   │   │   ├── client-only/
│   │   │   │   └── index.tsx
│   │   │   ├── image-card/
│   │   │   │   └── index.tsx
│   │   │   ├── image-upload/
│   │   │   │   └── index.tsx
│   │   │   ├── list-view/
│   │   │   │   └── index.tsx
│   │   │   ├── loader/
│   │   │   │   ├── buttonLoader.tsx
│   │   │   │   └── spinner.tsx
│   │   │   ├── project-header/
│   │   │   │   └── index.tsx
│   │   │   ├── project-page/
│   │   │   │   └── index.tsx
│   │   │   ├── tab-button/
│   │   │   │   └── index.tsx
│   │   │   ├── table-view/
│   │   │   │   └── index.tsx
│   │   │   ├── task-card/
│   │   │   │   └── index.tsx
│   │   │   ├── task-column/
│   │   │   │   └── index.tsx
│   │   │   └── timeline-view/
│   │   │       └── index.tsx
│   │   ├── header/
│   │   │   └── index.tsx
│   │   ├── home-page/
│   │   │   ├── index.tsx
│   │   │   └── root-home-page/
│   │   │       └── index.tsx
│   │   ├── modal/
│   │   │   ├── index.tsx
│   │   │   ├── modal-new-project/
│   │   │   │   └── index.tsx
│   │   │   ├── model-new-task/
│   │   │   │   └── index.tsx
│   │   │   └── model-share-project/
│   │   │       └── index.tsx
│   │   ├── navbar/
│   │   │   ├── home/
│   │   │   │   └── index.tsx
│   │   │   └── index.tsx
│   │   ├── priority-page/
│   │   │   └── index.tsx
│   │   ├── sidebar/
│   │   │   └── index.tsx
│   │   ├── task/
│   │   │   └── index.tsx
│   │   ├── timeline/
│   │   │   └── index.tsx
│   │   └── wrapper/
│   │       ├── dashboardWrapper.tsx
│   │       └── redux.tsx
│   ├── lib/
│   │   ├── prismadb.ts
│   │   └── utils.ts
│   ├── middleware.ts
│   ├── next.config.mjs
│   ├── package.json
│   ├── postcss.config.mjs
│   ├── prisma/
│   │   └── schema.prisma
│   ├── provider/
│   │   └── reduxProvider.tsx
│   ├── state/
│   │   ├── api.ts
│   │   └── index.ts
│   ├── tailwind.config.ts
│   ├── tsconfig.json
│   └── types/
│       └── type.ts
└── server/
    ├── .gitignore
    ├── ecosystem.config.js
    ├── package.json
    ├── prisma/
    │   ├── migrations/
    │   │   ├── 20250103002536_init/
    │   │   │   └── migration.sql
    │   │   └── migration_lock.toml
    │   ├── schema.prisma
    │   ├── seed.ts
    │   └── seedData/
    │       ├── attachment.json
    │       ├── comment.json
    │       ├── project.json
    │       ├── projectTeam.json
    │       ├── task.json
    │       ├── taskAssignment.json
    │       ├── team.json
    │       └── user.json
    ├── src/
    │   ├── controllers/
    │   │   ├── projectControllers.ts
    │   │   ├── searchControllers.ts
    │   │   ├── taskControllers.ts
    │   │   ├── teamControllers.ts
    │   │   └── usercontrollers.ts
    │   ├── index.ts
    │   └── routes/
    │       ├── projectRoutes.ts
    │       ├── searchRoutes.ts
    │       ├── taskRoute.ts
    │       ├── teamRoutes.ts
    │       └── userRoutes.ts
    └── tsconfig.json
Download .txt
SYMBOL INDEX (236 symbols across 105 files)

FILE: client/app/layout.tsx
  function RootLayout (line 13) | function RootLayout({

FILE: client/app/loading.tsx
  type Props (line 3) | type Props = {};
  function Loading (line 5) | function Loading({}: Props) {

FILE: client/app/page.tsx
  function Home (line 3) | function Home() {

FILE: client/app/priority/backlog/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/priority/high/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/priority/low/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/priority/medium/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/priority/urgent/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/projects/[id]/page.tsx
  type Props (line 3) | type Props = {
  function Page (line 9) | function Page({ params }: Props) {

FILE: client/app/search/page.tsx
  type Props (line 3) | type Props = {};
  function Page (line 5) | function Page({}: Props) {

FILE: client/app/settings/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/teams/page.tsx
  type Props (line 3) | type Props = {};
  function Page (line 5) | function Page({}: Props) {

FILE: client/app/timeline/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: client/app/users/page.tsx
  type Props (line 3) | type Props = {};
  function Page (line 5) | function Page({}: Props) {

FILE: client/components/Header/index.tsx
  type Props (line 3) | type Props = {
  function Header (line 9) | function Header({ name, buttonComponent, isSmallText }: Props) {

FILE: client/components/data/columns.tsx
  constant COLORS (line 84) | const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];

FILE: client/components/global/auth-provider/index.tsx
  type Props (line 7) | type Props = {
  function AuthProvider (line 20) | function AuthProvider({ children }: Props) {

FILE: client/components/global/border-view/index.tsx
  type Props (line 8) | type Props = {
  function BorderView (line 15) | function BorderView({ id, setIsModelNewTasOpen }: Props) {

FILE: client/components/global/loader/spinner.tsx
  type SpinnerProps (line 1) | type SpinnerProps = {

FILE: client/components/global/project-header/index.tsx
  type Props (line 16) | type Props = {
  function ProjectHeader (line 21) | function ProjectHeader({ activeTab, setActiveTab }: Props) {

FILE: client/components/global/tab-button/index.tsx
  type Props (line 3) | type Props = {
  function TabButton (line 10) | function TabButton({ activeTab, icon, name, setActiveTab }: Props) {

FILE: client/components/global/task-card/index.tsx
  type Props (line 6) | type Props = {
  function TaskCard (line 10) | function TaskCard({ task }: Props) {

FILE: client/components/global/task-column/index.tsx
  type Props (line 7) | type Props = {
  function TaskColumn (line 14) | function TaskColumn({ moveTask, setIsModelNewTasOpen, status, tasks }: P...

FILE: client/components/global/task/index.tsx
  type Props (line 7) | type Props = {
  function Task (line 11) | function Task({ task }: Props) {

FILE: client/components/home-page/index.tsx
  type Props (line 25) | type Props = {};
  function HomePage (line 27) | function HomePage({}: Props) {

FILE: client/components/list-view/index.tsx
  type Props (line 7) | type Props = {
  function ListView (line 12) | function ListView({ id, setIsModelNewTasOpen }: Props) {

FILE: client/components/modal/index.tsx
  type Props (line 6) | type Props = {
  function Modal (line 13) | function Modal({ children, isOpen, onClose, name }: Props) {

FILE: client/components/modal/modal-new-project/index.tsx
  type Props (line 7) | type Props = {
  function ModalNewProject (line 12) | function ModalNewProject({ isOpen, onClose }: Props) {

FILE: client/components/modal/model-new-task/index.tsx
  type Props (line 8) | type Props = {
  function ModelNewTask (line 14) | function ModelNewTask({ id, isOpen, onClose }: Props) {

FILE: client/components/navbar/index.tsx
  type Props (line 10) | type Props = {};
  function Navbar (line 12) | function Navbar({}: Props) {

FILE: client/components/priorityPage/index.tsx
  type Props (line 14) | type Props = {
  function PriorityPage (line 18) | function PriorityPage({ priority }: Props) {

FILE: client/components/project-card/index.tsx
  type Props (line 4) | type Props = {
  function ProjectCard (line 8) | function ProjectCard({ project }: Props) {

FILE: client/components/project-page/index.tsx
  type Props (line 11) | type Props = {
  function ProjectPage (line 15) | function ProjectPage({ id }: Props) {

FILE: client/components/search-page/index.tsx
  type Props (line 12) | type Props = {};
  function SearchPage (line 14) | function SearchPage({}: Props) {

FILE: client/components/settings-page/index.tsx
  type Props (line 4) | type Props = {};
  function SettingsPage (line 10) | function SettingsPage({}: Props) {

FILE: client/components/sidebar/index.tsx
  type Props (line 31) | type Props = {};
  function SideBar (line 33) | function SideBar({}: Props) {
  type SideBarLinksType (line 177) | interface SideBarLinksType {

FILE: client/components/table-view/index.tsx
  type Props (line 9) | type Props = {
  function TableView (line 14) | function TableView({ id, setIsModelNewTasOpen }: Props) {

FILE: client/components/team-page/index.tsx
  type Props (line 11) | type Props = {};
  function TeamPage (line 24) | function TeamPage({}: Props) {

FILE: client/components/timeline-view/index.tsx
  type Props (line 8) | type Props = {
  type TaskTypeItems (line 13) | type TaskTypeItems = "task" | "milestone" | "project";
  function Timeline (line 15) | function Timeline({ id, setIsModelNewTasOpen }: Props) {

FILE: client/components/timeline/index.tsx
  type Props (line 12) | type Props = {};
  function TimeLinePage (line 14) | function TimeLinePage({}: Props) {

FILE: client/components/user-card/index.tsx
  type Props (line 5) | type Props = {
  function UserCard (line 9) | function UserCard({ user }: Props) {

FILE: client/components/user-page/index.tsx
  type Props (line 12) | type Props = {};
  function UserPage (line 37) | function UserPage({}: Props) {

FILE: client/components/wrapper/dashboardWrapper.tsx
  type Props (line 9) | type Props = {
  function DashboardLayout (line 13) | function DashboardLayout({ children }: Props) {

FILE: client/components/wrapper/redux.tsx
  method getItem (line 28) | getItem(_key: any) {
  method setItem (line 31) | setItem(_key: any, value: any) {
  method removeItem (line 34) | removeItem(_key: any) {
  type AppStore (line 71) | type AppStore = ReturnType<typeof makeStore>;
  type RootState (line 72) | type RootState = ReturnType<AppStore["getState"]>;
  type AppDispatch (line 73) | type AppDispatch = AppStore["dispatch"];
  function StoreProvider (line 78) | function StoreProvider({

FILE: client/state/index.ts
  type initialStateTypes (line 3) | interface initialStateTypes {

FILE: client/types/type.ts
  type ProjectTypes (line 1) | interface ProjectTypes {
  type Status (line 9) | enum Status {
  type Priority (line 16) | enum Priority {
  type User (line 24) | interface User {
  type Attachment (line 33) | interface Attachment {
  type TasksTypes (line 41) | interface TasksTypes {
  type SearchResults (line 61) | interface SearchResults {
  type Team (line 67) | interface Team {
  type TaskTypeItems (line 74) | type TaskTypeItems = "task" | "milestone" | "project";

FILE: production-level-application/app/(auth)/layout.tsx
  type Props (line 3) | type Props = {
  function Layout (line 7) | function Layout({ children }: Props) {

FILE: production-level-application/app/(auth)/sign-in/[[...sign-in]]/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: production-level-application/app/(auth)/sign-up/[[...sign-up]]/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: production-level-application/app/api/move/[taskId]/route.tsx
  function PATCH (line 4) | async function PATCH(
  function DELETE (line 36) | async function DELETE(

FILE: production-level-application/app/api/projects/[projectId]/route.ts
  function DELETE (line 4) | async function DELETE(
  function PATCH (line 25) | async function PATCH(

FILE: production-level-application/app/api/projects/route.ts
  function GET (line 5) | async function GET(request: Request) {
  function POST (line 34) | async function POST(request: Request) {

FILE: production-level-application/app/api/tasks/[projectId]/route.ts
  type IParams (line 4) | interface IParams {
  function GET (line 8) | async function GET(request: Request, { params }: { params: IParams }) {
  function PATCH (line 37) | async function PATCH(

FILE: production-level-application/app/api/tasks/route.ts
  function POST (line 4) | async function POST(request: Request) {

FILE: production-level-application/app/api/tasks/user/[userId]/route.ts
  type IParams (line 4) | interface IParams {
  function GET (line 8) | async function GET(request: Request, { params }: { params: IParams }) {

FILE: production-level-application/app/api/user/[userId]/route.ts
  type IParams (line 4) | interface IParams {
  function GET (line 8) | async function GET(request: Request, { params }: { params: IParams }) {

FILE: production-level-application/app/api/user/route.ts
  function POST (line 4) | async function POST(request: Request) {

FILE: production-level-application/app/dashboard/layout.tsx
  type Props (line 5) | type Props = {
  function layout (line 9) | function layout({ children }: Props) {

FILE: production-level-application/app/dashboard/loading.tsx
  type Props (line 3) | type Props = {};
  function Loading (line 5) | function Loading({}: Props) {

FILE: production-level-application/app/dashboard/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | async function Page({}: Props) {

FILE: production-level-application/app/dashboard/priority/backlog/page.tsx
  type Props (line 5) | type Props = {};
  function Page (line 7) | function Page({}: Props) {

FILE: production-level-application/app/dashboard/priority/high/page.tsx
  type Props (line 5) | type Props = {};
  function Page (line 7) | function Page({}: Props) {

FILE: production-level-application/app/dashboard/priority/low/page.tsx
  type Props (line 5) | type Props = {};
  function Page (line 7) | function Page({}: Props) {

FILE: production-level-application/app/dashboard/priority/medium/page.tsx
  type Props (line 5) | type Props = {};
  function Page (line 7) | function Page({}: Props) {

FILE: production-level-application/app/dashboard/priority/urgent/page.tsx
  type Props (line 5) | type Props = {};
  function Page (line 7) | function Page({}: Props) {

FILE: production-level-application/app/dashboard/projects/[id]/page.tsx
  type Props (line 4) | type Props = {
  function Page (line 10) | function Page({ params }: Props) {

FILE: production-level-application/app/dashboard/timeline/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: production-level-application/app/layout.tsx
  function RootLayout (line 14) | function RootLayout({

FILE: production-level-application/app/loading.tsx
  type Props (line 3) | type Props = {};
  function Loading (line 5) | function Loading({}: Props) {

FILE: production-level-application/app/page.tsx
  type Props (line 4) | type Props = {};
  function Page (line 6) | function Page({}: Props) {

FILE: production-level-application/components/data/columns.tsx
  constant COLORS (line 84) | const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];

FILE: production-level-application/components/global/border-view/index.tsx
  type Props (line 7) | type Props = {
  function BorderView (line 14) | function BorderView({ id, setIsModelNewTasOpen }: Props) {

FILE: production-level-application/components/global/client-only/index.tsx
  type Props (line 5) | type Props = {
  function ClientOnly (line 9) | function ClientOnly({ children }: Props) {

FILE: production-level-application/components/global/image-card/index.tsx
  type Props (line 4) | type Props = {};
  function ImageCard (line 6) | function ImageCard({ src, aspectRatio, marginTop = "" }: ImageCardProps) {

FILE: production-level-application/components/global/image-upload/index.tsx
  type Props (line 12) | type Props = {
  function ImageUpload (line 17) | function ImageUpload({ setImageSrc, value }: Props) {

FILE: production-level-application/components/global/list-view/index.tsx
  type Props (line 7) | type Props = {
  function ListView (line 12) | function ListView({ id, setIsModelNewTasOpen }: Props) {

FILE: production-level-application/components/global/loader/buttonLoader.tsx
  type SpinnerProps (line 1) | type SpinnerProps = {

FILE: production-level-application/components/global/loader/spinner.tsx
  type SpinnerProps (line 1) | type SpinnerProps = {

FILE: production-level-application/components/global/project-header/index.tsx
  type Props (line 28) | type Props = {
  function ProjectHeader (line 36) | function ProjectHeader({

FILE: production-level-application/components/global/project-page/index.tsx
  type Props (line 15) | type Props = {
  function ProjectPage (line 19) | function ProjectPage({ id }: Props) {

FILE: production-level-application/components/global/tab-button/index.tsx
  type Props (line 3) | type Props = {
  function TabButton (line 10) | function TabButton({ activeTab, icon, name, setActiveTab }: Props) {

FILE: production-level-application/components/global/table-view/index.tsx
  type Props (line 9) | type Props = {
  function TableView (line 14) | function TableView({ id, setIsModelNewTasOpen }: Props) {

FILE: production-level-application/components/global/task-card/index.tsx
  type Props (line 6) | type Props = {
  function TaskCard (line 10) | function TaskCard({ task }: Props) {

FILE: production-level-application/components/global/task-column/index.tsx
  type Props (line 7) | type Props = {
  function TaskColumn (line 14) | function TaskColumn({ moveTask, setIsModelNewTasOpen, status, tasks }: P...

FILE: production-level-application/components/global/timeline-view/index.tsx
  type Props (line 8) | type Props = {
  type TaskTypeItems (line 13) | type TaskTypeItems = "task" | "milestone" | "project";
  function Timeline (line 15) | function Timeline({ id, setIsModelNewTasOpen }: Props) {

FILE: production-level-application/components/header/index.tsx
  type Props (line 3) | type Props = {
  function Header (line 9) | function Header({ name, buttonComponent, isSmallText }: Props) {

FILE: production-level-application/components/home-page/index.tsx
  type Props (line 27) | type Props = {
  function HomePage (line 32) | function HomePage({ projectId, project }: Props) {

FILE: production-level-application/components/home-page/root-home-page/index.tsx
  type Props (line 11) | type Props = {};
  function RootHomePage (line 13) | function RootHomePage({}: Props) {

FILE: production-level-application/components/modal/index.tsx
  type Props (line 7) | type Props = {
  function Modal (line 14) | function Modal({ children, isOpen, onClose, name }: Props) {

FILE: production-level-application/components/modal/modal-new-project/index.tsx
  type Props (line 9) | type Props = {
  function ModalNewProject (line 14) | function ModalNewProject({ isOpen, onClose }: Props) {

FILE: production-level-application/components/modal/model-new-task/index.tsx
  type Props (line 14) | type Props = {
  function ModelNewTask (line 21) | function ModelNewTask({ id, userId, isOpen, onClose }: Props) {

FILE: production-level-application/components/modal/model-share-project/index.tsx
  type Props (line 6) | type Props = {
  function ModelShareModel (line 15) | function ModelShareModel({

FILE: production-level-application/components/navbar/home/index.tsx
  type Props (line 10) | type Props = {};
  function HomeNavBar (line 46) | function HomeNavBar({}: Props) {

FILE: production-level-application/components/navbar/index.tsx
  type Props (line 7) | type Props = {};
  function Navbar (line 9) | function Navbar({}: Props) {

FILE: production-level-application/components/priority-page/index.tsx
  type Props (line 15) | type Props = {
  function PriorityPage (line 19) | function PriorityPage({ priority }: Props) {

FILE: production-level-application/components/sidebar/index.tsx
  type Props (line 28) | type Props = {};
  function SideBar (line 30) | function SideBar({}: Props) {
  type SideBarLinksType (line 205) | interface SideBarLinksType {

FILE: production-level-application/components/task/index.tsx
  type Props (line 11) | type Props = {
  function Task (line 15) | function Task({ task }: Props) {

FILE: production-level-application/components/timeline/index.tsx
  type Props (line 12) | type Props = {};
  function TimeLinePage (line 14) | function TimeLinePage({}: Props) {

FILE: production-level-application/components/wrapper/dashboardWrapper.tsx
  type Props (line 8) | type Props = {
  function DashboardLayout (line 12) | function DashboardLayout({ children }: Props) {

FILE: production-level-application/components/wrapper/redux.tsx
  method getItem (line 28) | getItem(_key: any) {
  method setItem (line 31) | setItem(_key: any, value: any) {
  method removeItem (line 34) | removeItem(_key: any) {
  type AppStore (line 71) | type AppStore = ReturnType<typeof makeStore>;
  type RootState (line 72) | type RootState = ReturnType<AppStore["getState"]>;
  type AppDispatch (line 73) | type AppDispatch = AppStore["dispatch"];
  function StoreProvider (line 78) | function StoreProvider({

FILE: production-level-application/provider/reduxProvider.tsx
  type Props (line 6) | type Props = {
  function ReduxProvider (line 10) | function ReduxProvider({ children }: Props) {

FILE: production-level-application/state/index.ts
  type initialStateTypes (line 3) | interface initialStateTypes {

FILE: production-level-application/types/type.ts
  type ProjectTypes (line 1) | interface ProjectTypes {
  type Status (line 11) | enum Status {
  type Priority (line 18) | enum Priority {
  type User (line 26) | interface User {
  type Attachment (line 36) | interface Attachment {
  type TasksTypes (line 44) | interface TasksTypes {
  type SearchResults (line 68) | interface SearchResults {
  type Team (line 74) | interface Team {
  type TaskTypeItems (line 81) | type TaskTypeItems = "task" | "milestone" | "project";
  type ImageCardProps (line 83) | interface ImageCardProps {

FILE: server/prisma/migrations/20250103002536_init/migration.sql
  type "User" (line 2) | CREATE TABLE "User" (
  type "Team" (line 13) | CREATE TABLE "Team" (
  type "Project" (line 23) | CREATE TABLE "Project" (
  type "ProjectTeam" (line 34) | CREATE TABLE "ProjectTeam" (
  type "Task" (line 43) | CREATE TABLE "Task" (
  type "TaskAssignment" (line 61) | CREATE TABLE "TaskAssignment" (
  type "Attachment" (line 70) | CREATE TABLE "Attachment" (
  type "Comment" (line 81) | CREATE TABLE "Comment" (
  type "User" (line 91) | CREATE UNIQUE INDEX "User_cognitoId_key" ON "User"("cognitoId")
  type "User" (line 94) | CREATE UNIQUE INDEX "User_username_key" ON "User"("username")

FILE: server/prisma/seed.ts
  function deleteAllData (line 7) | async function deleteAllData(orderedFileNames: string[]) {
  function main (line 24) | async function main() {
Condensed preview — 160 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (301K chars).
[
  {
    "path": "README.md",
    "chars": 3461,
    "preview": "<div align=\"center\">\n\n<img src=\"https://png.pngtree.com/png-vector/20220706/ourmid/pngtree-project-management-png-image_"
  },
  {
    "path": "aws-bucket-policy.json",
    "chars": 246,
    "preview": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"PublicReadGetObject\",\n            \"Effec"
  },
  {
    "path": "client/.eslintrc.json",
    "chars": 40,
    "preview": "{\n  \"extends\": \"next/core-web-vitals\"\n}\n"
  },
  {
    "path": "client/.gitignore",
    "chars": 391,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "client/.prettierrc",
    "chars": 49,
    "preview": "{\n  \"plugins\": [\"prettier-plugin-tailwindcss\"]\n}\n"
  },
  {
    "path": "client/README.md",
    "chars": 1383,
    "preview": "This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js"
  },
  {
    "path": "client/app/globals.css",
    "chars": 1249,
    "preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\nhtml,\n"
  },
  {
    "path": "client/app/layout.tsx",
    "chars": 624,
    "preview": "import DashboardWrapper from \"@/components/wrapper/dashboardWrapper\";\nimport type { Metadata } from \"next\";\nimport { Plu"
  },
  {
    "path": "client/app/loading.tsx",
    "chars": 247,
    "preview": "import { Spinner } from \"@/components/global/loader/spinner\";\n\ntype Props = {};\n\nfunction Loading({}: Props) {\n  return "
  },
  {
    "path": "client/app/page.tsx",
    "chars": 106,
    "preview": "import HomePage from \"@/components/home-page\";\n\nexport default function Home() {\n  return <HomePage />;\n}\n"
  },
  {
    "path": "client/app/priority/backlog/page.tsx",
    "chars": 220,
    "preview": "import PriorityPage from \"@/components/priorityPage\";\nimport { Priority } from \"@/types/type\";\n\ntype Props = {};\n\nfuncti"
  },
  {
    "path": "client/app/priority/high/page.tsx",
    "chars": 217,
    "preview": "import PriorityPage from \"@/components/priorityPage\";\nimport { Priority } from \"@/types/type\";\n\ntype Props = {};\n\nfuncti"
  },
  {
    "path": "client/app/priority/low/page.tsx",
    "chars": 216,
    "preview": "import PriorityPage from \"@/components/priorityPage\";\nimport { Priority } from \"@/types/type\";\n\ntype Props = {};\n\nfuncti"
  },
  {
    "path": "client/app/priority/medium/page.tsx",
    "chars": 219,
    "preview": "import PriorityPage from \"@/components/priorityPage\";\nimport { Priority } from \"@/types/type\";\n\ntype Props = {};\n\nfuncti"
  },
  {
    "path": "client/app/priority/urgent/page.tsx",
    "chars": 219,
    "preview": "import PriorityPage from \"@/components/priorityPage\";\nimport { Priority } from \"@/types/type\";\n\ntype Props = {};\n\nfuncti"
  },
  {
    "path": "client/app/projects/[id]/page.tsx",
    "chars": 225,
    "preview": "import ProjectPage from \"@/components/project-page\";\n\ntype Props = {\n  params: {\n    id: string;\n  };\n};\n\nfunction Page("
  },
  {
    "path": "client/app/search/page.tsx",
    "chars": 146,
    "preview": "import SearchPage from \"@/components/search-page\";\n\ntype Props = {};\n\nfunction Page({}: Props) {\n  return <SearchPage />"
  },
  {
    "path": "client/app/settings/page.tsx",
    "chars": 179,
    "preview": "import SettingsPage from \"@/components/settings-page\";\nimport React from \"react\";\n\ntype Props = {};\n\nfunction Page({}: P"
  },
  {
    "path": "client/app/teams/page.tsx",
    "chars": 140,
    "preview": "import TeamPage from \"@/components/team-page\";\n\ntype Props = {};\n\nfunction Page({}: Props) {\n  return <TeamPage />;\n}\n\ne"
  },
  {
    "path": "client/app/timeline/page.tsx",
    "chars": 174,
    "preview": "import TimeLinePage from \"@/components/timeline\";\nimport React from \"react\";\n\ntype Props = {};\n\nfunction Page({}: Props)"
  },
  {
    "path": "client/app/users/page.tsx",
    "chars": 140,
    "preview": "import UserPage from \"@/components/user-page\";\n\ntype Props = {};\n\nfunction Page({}: Props) {\n  return <UserPage />;\n}\n\ne"
  },
  {
    "path": "client/components/Header/index.tsx",
    "chars": 460,
    "preview": "import React from \"react\";\n\ntype Props = {\n  name: string;\n  buttonComponent?: any;\n  isSmallText?: boolean;\n};\n\nfunctio"
  },
  {
    "path": "client/components/data/columns.tsx",
    "chars": 3564,
    "preview": "import {\n  GridColDef,\n  GridToolbarContainer,\n  GridToolbarExport,\n  GridToolbarFilterButton,\n} from \"@mui/x-data-grid\""
  },
  {
    "path": "client/components/global/auth-provider/index.tsx",
    "chars": 852,
    "preview": "import { formFields } from \"@/components/data/columns\";\nimport { Authenticator } from \"@aws-amplify/ui-react\";\nimport \"@"
  },
  {
    "path": "client/components/global/border-view/index.tsx",
    "chars": 1334,
    "preview": "import { useGetTasksQuery, useUpdateTasksMutation } from \"@/state/api\";\nimport React from \"react\";\nimport { DndProvider "
  },
  {
    "path": "client/components/global/loader/spinner.tsx",
    "chars": 1576,
    "preview": "type SpinnerProps = {\n  color?: string;\n};\n\nexport const Spinner = ({ color }: SpinnerProps) => {\n  return (\n    <div\n  "
  },
  {
    "path": "client/components/global/project-header/index.tsx",
    "chars": 2998,
    "preview": "import TabButton from \"@/components/global/tab-button\";\nimport Header from \"@/components/Header\";\nimport ModalNewProject"
  },
  {
    "path": "client/components/global/tab-button/index.tsx",
    "chars": 722,
    "preview": "import React from \"react\";\n\ntype Props = {\n  name: string;\n  icon: React.ReactNode;\n  setActiveTab: (tabName: string) =>"
  },
  {
    "path": "client/components/global/task/index.tsx",
    "chars": 4718,
    "preview": "import { TasksTypes } from \"@/types/type\";\nimport { format } from \"date-fns\";\nimport { EllipsisVertical, MessageSquareMo"
  },
  {
    "path": "client/components/global/task-card/index.tsx",
    "chars": 1908,
    "preview": "import { TasksTypes } from \"@/types/type\";\nimport { format } from \"date-fns\";\nimport Image from \"next/image\";\nimport Rea"
  },
  {
    "path": "client/components/global/task-column/index.tsx",
    "chars": 2498,
    "preview": "import { EllipsisVertical, Plus } from \"lucide-react\";\nimport React from \"react\";\nimport { useDrop } from \"react-dnd\";\ni"
  },
  {
    "path": "client/components/home-page/index.tsx",
    "chars": 4634,
    "preview": "\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";\nimport { useGetProjectsQuery, useGetT"
  },
  {
    "path": "client/components/list-view/index.tsx",
    "chars": 1255,
    "preview": "import { useGetTasksQuery } from \"@/state/api\";\nimport { TasksTypes } from \"@/types/type\";\nimport { Spinner } from \"../g"
  },
  {
    "path": "client/components/modal/index.tsx",
    "chars": 1045,
    "preview": "import Header from \"@/components/Header\";\nimport { X } from \"lucide-react\";\nimport React from \"react\";\nimport ReactDOM f"
  },
  {
    "path": "client/components/modal/modal-new-project/index.tsx",
    "chars": 2987,
    "preview": "import { Spinner } from \"@/components/global/loader/spinner\";\nimport { useCreateProjectMutation } from \"@/state/api\";\nim"
  },
  {
    "path": "client/components/modal/model-new-task/index.tsx",
    "chars": 5856,
    "preview": "import { Spinner } from \"@/components/global/loader/spinner\";\nimport { useCreateTasksMutation } from \"@/state/api\";\nimpo"
  },
  {
    "path": "client/components/navbar/index.tsx",
    "chars": 3436,
    "preview": "import { setIsDarkMode, setIsSidebarCollapsed } from \"@/state\";\nimport { useGetAuthUserQuery } from \"@/state/api\";\nimpor"
  },
  {
    "path": "client/components/priorityPage/index.tsx",
    "chars": 2962,
    "preview": "\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";\nimport { useGetAuthUserQuery, useGetT"
  },
  {
    "path": "client/components/project-card/index.tsx",
    "chars": 433,
    "preview": "import { ProjectTypes } from \"@/types/type\";\nimport React from \"react\";\n\ntype Props = {\n  project: ProjectTypes;\n};\n\nfun"
  },
  {
    "path": "client/components/project-page/index.tsx",
    "chars": 1260,
    "preview": "\"use client\";\n\nimport { useState } from \"react\";\nimport BorderView from \"../global/border-view\";\nimport ProjectHeader fr"
  },
  {
    "path": "client/components/search-page/index.tsx",
    "chars": 2096,
    "preview": "\"use client\";\n\nimport { useSearchQuery } from \"@/state/api\";\nimport { debounce } from \"lodash\";\nimport { useEffect, useS"
  },
  {
    "path": "client/components/settings-page/index.tsx",
    "chars": 1077,
    "preview": "import Header from \"../Header\";\nimport { userSettings } from \"../data/columns\";\n\ntype Props = {};\n\nconst labelStyles = \""
  },
  {
    "path": "client/components/sidebar/index.tsx",
    "chars": 6926,
    "preview": "\"use client\";\n\nimport { setIsSidebarCollapsed } from \"@/state\";\nimport { useGetAuthUserQuery, useGetProjectsQuery } from"
  },
  {
    "path": "client/components/table-view/index.tsx",
    "chars": 1434,
    "preview": "import { columns } from \"@/components/data/columns\";\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";"
  },
  {
    "path": "client/components/team-page/index.tsx",
    "chars": 1355,
    "preview": "\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";\nimport { useGetTeamsQuery } from \"@/s"
  },
  {
    "path": "client/components/timeline/index.tsx",
    "chars": 2921,
    "preview": "\"use client\";\n\nimport { useGetProjectsQuery } from \"@/state/api\";\nimport { TaskTypeItems } from \"@/types/type\";\nimport {"
  },
  {
    "path": "client/components/timeline-view/index.tsx",
    "chars": 3264,
    "preview": "import { useGetTasksQuery } from \"@/state/api\";\nimport { DisplayOption, Gantt, ViewMode } from \"gantt-task-react\";\nimpor"
  },
  {
    "path": "client/components/user-card/index.tsx",
    "chars": 628,
    "preview": "import { User } from \"@/types/type\";\nimport Image from \"next/image\";\nimport React from \"react\";\n\ntype Props = {\n  user: "
  },
  {
    "path": "client/components/user-page/index.tsx",
    "chars": 1768,
    "preview": "\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";\nimport { useGetUsersQuery } from \"@/s"
  },
  {
    "path": "client/components/wrapper/dashboardWrapper.tsx",
    "chars": 1269,
    "preview": "\"use client\";\n\nimport Navbar from \"@/components/navbar\";\nimport SideBar from \"@/components/sidebar\";\nimport React, { use"
  },
  {
    "path": "client/components/wrapper/redux.tsx",
    "chars": 2386,
    "preview": "import globalReducer from \"@/state\";\nimport { api } from \"@/state/api\";\nimport { combineReducers, configureStore } from "
  },
  {
    "path": "client/lib/utils.ts",
    "chars": 1013,
    "preview": "export const dataGridClassNames =\n  \"border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-seconda"
  },
  {
    "path": "client/next.config.mjs",
    "chars": 287,
    "preview": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  images: {\n    remotePatterns: [\n      {\n        protocol"
  },
  {
    "path": "client/package.json",
    "chars": 1300,
    "preview": "{\n  \"name\": \"client\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next "
  },
  {
    "path": "client/postcss.config.mjs",
    "chars": 135,
    "preview": "/** @type {import('postcss-load-config').Config} */\nconst config = {\n  plugins: {\n    tailwindcss: {},\n  },\n};\n\nexport d"
  },
  {
    "path": "client/state/api.ts",
    "chars": 3521,
    "preview": "import {\n  ProjectTypes,\n  SearchResults,\n  TasksTypes,\n  Team,\n  User,\n} from \"@/types/type\";\nimport { createApi, fetch"
  },
  {
    "path": "client/state/index.ts",
    "chars": 706,
    "preview": "import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\n\nexport interface initialStateTypes {\n  isSidebarCollapse"
  },
  {
    "path": "client/tailwind.config.ts",
    "chars": 888,
    "preview": "import type { Config } from \"tailwindcss\";\n\nexport default {\n  darkMode: \"class\",\n  content: [\n    \"./pages/**/*.{js,ts,"
  },
  {
    "path": "client/tsconfig.json",
    "chars": 574,
    "preview": "{\n  \"compilerOptions\": {\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n  "
  },
  {
    "path": "client/types/type.ts",
    "chars": 1346,
    "preview": "export interface ProjectTypes {\n  id: number;\n  name: string;\n  description?: string;\n  startDate?: string;\n  endDate?: "
  },
  {
    "path": "lamda_trigger.mjs",
    "chars": 980,
    "preview": "import https from \"node:https\";\n\nexport const handler = async (event) => {\n  const postdata = JSON.stringify({\n    usern"
  },
  {
    "path": "production-level-application/.eslintrc.json",
    "chars": 40,
    "preview": "{\n  \"extends\": \"next/core-web-vitals\"\n}\n"
  },
  {
    "path": "production-level-application/.gitignore",
    "chars": 392,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "production-level-application/README.md",
    "chars": 1383,
    "preview": "This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js"
  },
  {
    "path": "production-level-application/actions/index.ts",
    "chars": 230,
    "preview": "import { currentUser } from \"@clerk/nextjs/server\";\nimport { redirect } from \"next/navigation\";\n\nexport const onCurrentU"
  },
  {
    "path": "production-level-application/app/(auth)/layout.tsx",
    "chars": 237,
    "preview": "import React from \"react\";\n\ntype Props = {\n  children: React.ReactNode;\n};\n\nfunction Layout({ children }: Props) {\n  ret"
  },
  {
    "path": "production-level-application/app/(auth)/sign-in/[[...sign-in]]/page.tsx",
    "chars": 158,
    "preview": "import { SignIn } from \"@clerk/nextjs\";\nimport React from \"react\";\n\ntype Props = {};\n\nfunction Page({}: Props) {\n  retur"
  },
  {
    "path": "production-level-application/app/(auth)/sign-up/[[...sign-up]]/page.tsx",
    "chars": 158,
    "preview": "import { SignUp } from \"@clerk/nextjs\";\nimport React from \"react\";\n\ntype Props = {};\n\nfunction Page({}: Props) {\n  retur"
  },
  {
    "path": "production-level-application/app/api/move/[taskId]/route.tsx",
    "chars": 1230,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\nexport async function PATCH(\n  request"
  },
  {
    "path": "production-level-application/app/api/projects/[projectId]/route.ts",
    "chars": 1591,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\nexport async function DELETE(\n  reques"
  },
  {
    "path": "production-level-application/app/api/projects/route.ts",
    "chars": 1576,
    "preview": "import { onCurrentUser } from \"@/actions\";\nimport prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/serve"
  },
  {
    "path": "production-level-application/app/api/tasks/[projectId]/route.ts",
    "chars": 1797,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\ninterface IParams {\n  projectId?: stri"
  },
  {
    "path": "production-level-application/app/api/tasks/route.ts",
    "chars": 941,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\nexport async function POST(request: Re"
  },
  {
    "path": "production-level-application/app/api/tasks/user/[userId]/route.ts",
    "chars": 625,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\ninterface IParams {\n  userId?: string;"
  },
  {
    "path": "production-level-application/app/api/user/[userId]/route.ts",
    "chars": 497,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\ninterface IParams {\n  userId?: string;"
  },
  {
    "path": "production-level-application/app/api/user/route.ts",
    "chars": 934,
    "preview": "import prisma from \"@/lib/prismadb\";\nimport { NextResponse } from \"next/server\";\n\nexport async function POST(request: Re"
  },
  {
    "path": "production-level-application/app/dashboard/layout.tsx",
    "chars": 365,
    "preview": "import DashboardWrapper from \"@/components/wrapper/dashboardWrapper\";\nimport React from \"react\";\nimport { ToastContainer"
  },
  {
    "path": "production-level-application/app/dashboard/loading.tsx",
    "chars": 160,
    "preview": "import { Spinner } from \"@/components/global/loader/spinner\";\n\ntype Props = {};\n\nfunction Loading({}: Props) {\n  return "
  },
  {
    "path": "production-level-application/app/dashboard/page.tsx",
    "chars": 274,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport RootHomePage from \"@/components/home-page/root-home-pag"
  },
  {
    "path": "production-level-application/app/dashboard/priority/backlog/page.tsx",
    "chars": 326,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport PriorityPage from \"@/components/priority-page\";\nimport "
  },
  {
    "path": "production-level-application/app/dashboard/priority/high/page.tsx",
    "chars": 323,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport PriorityPage from \"@/components/priority-page\";\nimport "
  },
  {
    "path": "production-level-application/app/dashboard/priority/low/page.tsx",
    "chars": 323,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport PriorityPage from \"@/components/priority-page\";\nimport "
  },
  {
    "path": "production-level-application/app/dashboard/priority/medium/page.tsx",
    "chars": 325,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport PriorityPage from \"@/components/priority-page\";\nimport "
  },
  {
    "path": "production-level-application/app/dashboard/priority/urgent/page.tsx",
    "chars": 325,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport PriorityPage from \"@/components/priority-page\";\nimport "
  },
  {
    "path": "production-level-application/app/dashboard/projects/[id]/page.tsx",
    "chars": 337,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport ProjectPage from \"@/components/global/project-page\";\n\nt"
  },
  {
    "path": "production-level-application/app/dashboard/timeline/page.tsx",
    "chars": 252,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport TimeLinePage from \"@/components/timeline\";\n\ntype Props "
  },
  {
    "path": "production-level-application/app/globals.css",
    "chars": 1249,
    "preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\nhtml,\n"
  },
  {
    "path": "production-level-application/app/layout.tsx",
    "chars": 707,
    "preview": "import ReduxProvider from \"@/provider/reduxProvider\";\nimport { ClerkProvider } from \"@clerk/nextjs\";\nimport type { Metad"
  },
  {
    "path": "production-level-application/app/loading.tsx",
    "chars": 160,
    "preview": "import { Spinner } from \"@/components/global/loader/spinner\";\n\ntype Props = {};\n\nfunction Loading({}: Props) {\n  return "
  },
  {
    "path": "production-level-application/app/page.tsx",
    "chars": 251,
    "preview": "import ClientOnly from \"@/components/global/client-only\";\nimport HomeNavBar from \"@/components/navbar/home\";\n\ntype Props"
  },
  {
    "path": "production-level-application/components/data/columns.tsx",
    "chars": 3564,
    "preview": "import {\n  GridColDef,\n  GridToolbarContainer,\n  GridToolbarExport,\n  GridToolbarFilterButton,\n} from \"@mui/x-data-grid\""
  },
  {
    "path": "production-level-application/components/global/border-view/index.tsx",
    "chars": 1284,
    "preview": "import { useGetTasksQuery, useUpdateTasksMutation } from \"@/state/api\";\nimport { DndProvider } from \"react-dnd\";\nimport "
  },
  {
    "path": "production-level-application/components/global/client-only/index.tsx",
    "chars": 348,
    "preview": "\"use client\";\n\nimport { motion } from \"framer-motion\";\n\ntype Props = {\n  children: React.ReactNode;\n};\n\nfunction ClientO"
  },
  {
    "path": "production-level-application/components/global/image-card/index.tsx",
    "chars": 358,
    "preview": "import { ImageCardProps } from \"@/types/type\";\nimport React from \"react\";\n\ntype Props = {};\n\nfunction ImageCard({ src, a"
  },
  {
    "path": "production-level-application/components/global/image-upload/index.tsx",
    "chars": 1871,
    "preview": "\"use client\";\n\nimport { Camera, PhoneOutgoingIcon } from \"lucide-react\";\nimport { CldUploadWidget } from \"next-cloudinar"
  },
  {
    "path": "production-level-application/components/global/list-view/index.tsx",
    "chars": 1228,
    "preview": "import { useGetTasksQuery } from \"@/state/api\";\nimport { TasksTypes } from \"@/types/type\";\nimport { Spinner } from \"../l"
  },
  {
    "path": "production-level-application/components/global/loader/buttonLoader.tsx",
    "chars": 1550,
    "preview": "type SpinnerProps = {\n  color?: string;\n};\n\nexport const ButtonLoader = ({ color }: SpinnerProps) => {\n  return (\n    <d"
  },
  {
    "path": "production-level-application/components/global/loader/spinner.tsx",
    "chars": 1580,
    "preview": "type SpinnerProps = {\n  color?: string;\n};\n\nexport const Spinner = ({ color }: SpinnerProps) => {\n  return (\n    <div\n  "
  },
  {
    "path": "production-level-application/components/global/project-header/index.tsx",
    "chars": 6770,
    "preview": "import Header from \"@/components/header\";\nimport ModalNewProject from \"@/components/modal/modal-new-project\";\nimport Mod"
  },
  {
    "path": "production-level-application/components/global/project-page/index.tsx",
    "chars": 2080,
    "preview": "\"use client\";\n\nimport ModelNewTask from \"@/components/modal/model-new-task\";\nimport { useGetProjectsQuery } from \"@/stat"
  },
  {
    "path": "production-level-application/components/global/tab-button/index.tsx",
    "chars": 722,
    "preview": "import React from \"react\";\n\ntype Props = {\n  name: string;\n  icon: React.ReactNode;\n  setActiveTab: (tabName: string) =>"
  },
  {
    "path": "production-level-application/components/global/table-view/index.tsx",
    "chars": 1424,
    "preview": "import { columns } from \"@/components/data/columns\";\nimport Header from \"@/components/header\";\nimport { useAppSelector }"
  },
  {
    "path": "production-level-application/components/global/task-card/index.tsx",
    "chars": 1910,
    "preview": "import { TasksTypes } from \"@/types/type\";\nimport { format } from \"date-fns\";\nimport Image from \"next/image\";\nimport Rea"
  },
  {
    "path": "production-level-application/components/global/task-column/index.tsx",
    "chars": 2524,
    "preview": "import { EllipsisVertical, Plus } from \"lucide-react\";\nimport React from \"react\";\nimport { useDrop } from \"react-dnd\";\ni"
  },
  {
    "path": "production-level-application/components/global/timeline-view/index.tsx",
    "chars": 3243,
    "preview": "import { useAppSelector } from \"@/components/wrapper/redux\";\nimport { useGetTasksQuery } from \"@/state/api\";\nimport { Di"
  },
  {
    "path": "production-level-application/components/header/index.tsx",
    "chars": 480,
    "preview": "import React from \"react\";\n\ntype Props = {\n  name: string;\n  buttonComponent?: any;\n  isSmallText?: boolean;\n};\n\nfunctio"
  },
  {
    "path": "production-level-application/components/home-page/index.tsx",
    "chars": 6813,
    "preview": "/* eslint-disable @next/next/no-img-element */\n\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/li"
  },
  {
    "path": "production-level-application/components/home-page/root-home-page/index.tsx",
    "chars": 2483,
    "preview": "/* eslint-disable @next/next/no-img-element */\n\"use client\";\n\nimport ModalNewProject from \"@/components/modal/modal-new-"
  },
  {
    "path": "production-level-application/components/modal/index.tsx",
    "chars": 1154,
    "preview": "import { X } from \"lucide-react\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport ClientOnly from \"."
  },
  {
    "path": "production-level-application/components/modal/modal-new-project/index.tsx",
    "chars": 3389,
    "preview": "import { ButtonLoader } from \"@/components/global/loader/buttonLoader\";\nimport { useCreateProjectMutation } from \"@/stat"
  },
  {
    "path": "production-level-application/components/modal/model-new-task/index.tsx",
    "chars": 6855,
    "preview": "import ImageUpload from \"@/components/global/image-upload\";\nimport { ButtonLoader } from \"@/components/global/loader/but"
  },
  {
    "path": "production-level-application/components/modal/model-share-project/index.tsx",
    "chars": 4174,
    "preview": "import { useState } from \"react\";\nimport Modal from \"..\";\nimport { useUpdateProjectAuthorsMutation } from \"@/state/api\";"
  },
  {
    "path": "production-level-application/components/navbar/home/index.tsx",
    "chars": 8390,
    "preview": "\"use client\";\n\nimport ImageCard from \"@/components/global/image-card\";\nimport { useAppDispatch, useAppSelector } from \"@"
  },
  {
    "path": "production-level-application/components/navbar/index.tsx",
    "chars": 2701,
    "preview": "import { setIsDarkMode, setIsSidebarCollapsed } from \"@/state\";\nimport { UserButton } from \"@clerk/nextjs\";\nimport { Men"
  },
  {
    "path": "production-level-application/components/priority-page/index.tsx",
    "chars": 2917,
    "preview": "\"use client\";\n\nimport { dataGridClassNames, dataGridSxStyles } from \"@/lib/utils\";\nimport { useGetTasksByUserQuery } fro"
  },
  {
    "path": "production-level-application/components/sidebar/index.tsx",
    "chars": 8269,
    "preview": "\"use client\";\n\nimport { setIsSidebarCollapsed } from \"@/state\";\nimport { useGetProjectsQuery } from \"@/state/api\";\nimpor"
  },
  {
    "path": "production-level-application/components/task/index.tsx",
    "chars": 7779,
    "preview": "import { useDeleteTasksMutation } from \"@/state/api\";\nimport { TasksTypes } from \"@/types/type\";\nimport { useUser } from"
  },
  {
    "path": "production-level-application/components/timeline/index.tsx",
    "chars": 2919,
    "preview": "\"use client\";\n\nimport { useGetProjectsQuery } from \"@/state/api\";\nimport { TaskTypeItems } from \"@/types/type\";\nimport {"
  },
  {
    "path": "production-level-application/components/wrapper/dashboardWrapper.tsx",
    "chars": 1103,
    "preview": "\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport Navbar from \"../navbar\";\nimport SideBar from \"../sidebar"
  },
  {
    "path": "production-level-application/components/wrapper/redux.tsx",
    "chars": 2386,
    "preview": "import globalReducer from \"@/state\";\nimport { api } from \"@/state/api\";\nimport { combineReducers, configureStore } from "
  },
  {
    "path": "production-level-application/lib/prismadb.ts",
    "chars": 260,
    "preview": "import { PrismaClient } from \"@prisma/client\";\n\ndeclare global {\n  var prisma: PrismaClient | undefined;\n}\n\nconst client"
  },
  {
    "path": "production-level-application/lib/utils.ts",
    "chars": 1013,
    "preview": "export const dataGridClassNames =\n  \"border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-seconda"
  },
  {
    "path": "production-level-application/middleware.ts",
    "chars": 571,
    "preview": "import { clerkMiddleware, createRouteMatcher } from \"@clerk/nextjs/server\";\n\nconst isProtectedRoute = createRouteMatcher"
  },
  {
    "path": "production-level-application/next.config.mjs",
    "chars": 513,
    "preview": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  images: {\n    remotePatterns: [\n      {\n        protocol"
  },
  {
    "path": "production-level-application/package.json",
    "chars": 1240,
    "preview": "{\n  \"name\": \"pm-app\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next "
  },
  {
    "path": "production-level-application/postcss.config.mjs",
    "chars": 135,
    "preview": "/** @type {import('postcss-load-config').Config} */\nconst config = {\n  plugins: {\n    tailwindcss: {},\n  },\n};\n\nexport d"
  },
  {
    "path": "production-level-application/prisma/schema.prisma",
    "chars": 3553,
    "preview": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for "
  },
  {
    "path": "production-level-application/provider/reduxProvider.tsx",
    "chars": 278,
    "preview": "\"use client\";\n\nimport StoreProvider from \"@/components/wrapper/redux\";\nimport React from \"react\";\n\ntype Props = {\n  chil"
  },
  {
    "path": "production-level-application/state/api.ts",
    "chars": 3712,
    "preview": "import { ProjectTypes, TasksTypes, User } from \"@/types/type\";\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolk"
  },
  {
    "path": "production-level-application/state/index.ts",
    "chars": 706,
    "preview": "import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\n\nexport interface initialStateTypes {\n  isSidebarCollapse"
  },
  {
    "path": "production-level-application/tailwind.config.ts",
    "chars": 888,
    "preview": "import type { Config } from \"tailwindcss\";\n\nexport default {\n  darkMode: \"class\",\n  content: [\n    \"./pages/**/*.{js,ts,"
  },
  {
    "path": "production-level-application/tsconfig.json",
    "chars": 574,
    "preview": "{\n  \"compilerOptions\": {\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n  "
  },
  {
    "path": "production-level-application/types/type.ts",
    "chars": 1580,
    "preview": "export interface ProjectTypes {\n  id: number;\n  name: string;\n  description?: string;\n  startDate?: string;\n  endDate?: "
  },
  {
    "path": "server/.gitignore",
    "chars": 401,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "server/ecosystem.config.js",
    "chars": 183,
    "preview": "module.exports = {\n  apps: [\n    {\n      name: \"project-management\",\n      script: \"npm\",\n      args: \"run dev\",\n      e"
  },
  {
    "path": "server/package.json",
    "chars": 964,
    "preview": "{\n  \"name\": \"server\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test spec"
  },
  {
    "path": "server/prisma/migrations/20250103002536_init/migration.sql",
    "chars": 4134,
    "preview": "-- CreateTable\nCREATE TABLE \"User\" (\n    \"userId\" SERIAL NOT NULL,\n    \"cognitoId\" TEXT NOT NULL,\n    \"username\" TEXT NO"
  },
  {
    "path": "server/prisma/migrations/migration_lock.toml",
    "chars": 127,
    "preview": "# Please do not edit this file manually\n# It should be added in your version-control system (e.g., Git)\nprovider = \"post"
  },
  {
    "path": "server/prisma/schema.prisma",
    "chars": 3067,
    "preview": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for "
  },
  {
    "path": "server/prisma/seed.ts",
    "chars": 1700,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nconst prisma = new PrismaC"
  },
  {
    "path": "server/prisma/seedData/attachment.json",
    "chars": 1230,
    "preview": "[\n  {\n    \"id\": 1,\n    \"fileURL\": \"i1.jpg\",\n    \"fileName\": \"DesignDoc.pdf\",\n    \"taskId\": 1,\n    \"uploadedById\": 1\n  },"
  },
  {
    "path": "server/prisma/seedData/comment.json",
    "chars": 3328,
    "preview": "[\n  {\n    \"id\": 1,\n    \"text\": \"We need to update this design to include new specifications.\",\n    \"taskId\": 1,\n    \"use"
  },
  {
    "path": "server/prisma/seedData/project.json",
    "chars": 1861,
    "preview": "[\n  {\n    \"id\": 1,\n    \"name\": \"Apollo\",\n    \"description\": \"A space exploration project.\",\n    \"startDate\": \"2023-01-01"
  },
  {
    "path": "server/prisma/seedData/projectTeam.json",
    "chars": 894,
    "preview": "[\n  { \"id\": 1, \"teamId\": 1, \"projectId\": 1 },\n  { \"id\": 2, \"teamId\": 2, \"projectId\": 1 },\n  { \"id\": 3, \"teamId\": 3, \"pro"
  },
  {
    "path": "server/prisma/seedData/task.json",
    "chars": 13674,
    "preview": "[\n  {\n    \"id\": 1,\n    \"title\": \"Task 1\",\n    \"description\": \"Design the main module.\",\n    \"status\": \"Work In Progress\""
  },
  {
    "path": "server/prisma/seedData/taskAssignment.json",
    "chars": 1287,
    "preview": "[\n  { \"id\": 1, \"userId\": 1, \"taskId\": 1 },\n  { \"id\": 2, \"userId\": 2, \"taskId\": 2 },\n  { \"id\": 3, \"userId\": 3, \"taskId\": "
  },
  {
    "path": "server/prisma/seedData/team.json",
    "chars": 537,
    "preview": "[\n  {\n    \"teamName\": \"Quantum Innovations\",\n    \"productOwnerUserId\": 11,\n    \"projectManagerUserId\": 2\n  },\n  {\n    \"t"
  },
  {
    "path": "server/prisma/seedData/user.json",
    "chars": 2959,
    "preview": "[\n  {\n    \"username\": \"AliceJones\",\n    \"teamId\": 1,\n    \"profilePictureUrl\": \"p1.jpeg\",\n    \"cognitoId\": \"123e4567-e89b"
  },
  {
    "path": "server/src/controllers/projectControllers.ts",
    "chars": 915,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport { Request, Response } from \"express\";\n\nconst prisma = new PrismaCl"
  },
  {
    "path": "server/src/controllers/searchControllers.ts",
    "chars": 969,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport { Request, Response } from \"express\";\n\nconst prisma = new PrismaCl"
  },
  {
    "path": "server/src/controllers/taskControllers.ts",
    "chars": 2386,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport { Request, Response } from \"express\";\n\nconst prisma = new PrismaCl"
  },
  {
    "path": "server/src/controllers/teamControllers.ts",
    "chars": 1013,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport { Request, Response } from \"express\";\n\nconst prisma = new PrismaCl"
  },
  {
    "path": "server/src/controllers/usercontrollers.ts",
    "chars": 1292,
    "preview": "import { PrismaClient } from \"@prisma/client\";\nimport { Request, Response } from \"express\";\n\nconst prisma = new PrismaCl"
  },
  {
    "path": "server/src/index.ts",
    "chars": 1152,
    "preview": "import bodyParser from \"body-parser\";\nimport cors from \"cors\";\nimport dotenv from \"dotenv\";\nimport express, { Request, R"
  },
  {
    "path": "server/src/routes/projectRoutes.ts",
    "chars": 228,
    "preview": "import { Router } from \"express\";\nimport { createProject, getProjects } from \"../controllers/projectControllers\";\n\nconst"
  },
  {
    "path": "server/src/routes/searchRoutes.ts",
    "chars": 169,
    "preview": "import { Router } from \"express\";\nimport { search } from \"../controllers/searchControllers\";\n\nconst router = Router();\n\n"
  },
  {
    "path": "server/src/routes/taskRoute.ts",
    "chars": 340,
    "preview": "import { Router } from \"express\";\nimport {\n  createTasks,\n  getTasks,\n  getUserTasks,\n  updateTasks,\n} from \"../controll"
  },
  {
    "path": "server/src/routes/teamRoutes.ts",
    "chars": 171,
    "preview": "import { Router } from \"express\";\nimport { getTeams } from \"../controllers/teamControllers\";\n\nconst router = Router();\n\n"
  },
  {
    "path": "server/src/routes/userRoutes.ts",
    "chars": 254,
    "preview": "import { Router } from \"express\";\nimport { getUser, getUsers, postUser } from \"../controllers/usercontrollers\";\n\nconst r"
  },
  {
    "path": "server/tsconfig.json",
    "chars": 12410,
    "preview": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig to read more about this file */\n\n    /* Projects */\n    //"
  }
]

About this extraction

This page contains the full source code of the SashenJayathilaka/ChatGPT-Clone GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 160 files (266.0 KB), approximately 77.5k tokens, and a symbol index with 236 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!