Untitled

Anonymous
plain_text
02/26/2026 3:51 AM
10.7 KB
12
Indexable
"use client";

import { ColumnDef } from '@tanstack/react-table';

import { Button } from '@/components/ui/button';
import { ArrowUpDown, MoreHorizontal, Eye, Pencil, Trash, Edit } from 'lucide-react';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import Link from 'next/link';
import { Badge } from '@/components/ui/badge';
import { Client } from '@/lib/types';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { STATUS_DETAILS } from '@/lib/constants/status-details';
import { usePermission } from '@/hooks/use-permission';

export type Project = {
    id: string;
    name: string;
    categories: string;
    theme: string;
    executionOrders: number;
    startDate: string;
    endDate: string;
    businessUnit: string;
    duration: number;
    zone: string;
    districts: string;
    department: string;
    budget: string;
    pm: string;
    client: Client
    po_number: string;
    status: 'ACTIVE' | 'COMPLETED' | 'NEW' | 'Pending Approval';
    is_submitted: number;
};

export const getColumns = (hasAnyPermission: (permission: string[]) => boolean): ColumnDef<Project>[] => [
    {
        id: 'actions',
        header: '#',
        cell: ({ row }) => {
            const project = row.original;
            const {hasAllPermissions} = usePermission();

            if (project.is_submitted !== 1 && hasAnyPermission(['edit projects'])) {
                return (
                    <Button asChild size="sm" variant="outline" className="h-8">
                        <Link href={`/projects/setup/${project.id}`}>
                            Complete
                        </Link>
                    </Button>
                );
            }

            return (
                <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                        <Button variant="ghost" className="h-8 w-8 p-0">
                            <span className="sr-only">Open menu</span>
                            <MoreHorizontal className="h-4 w-4" />
                        </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end">
                        <DropdownMenuLabel>Actions</DropdownMenuLabel>
                        {(hasAnyPermission(['view all projects', 'view assign projects'])) && (
                            <DropdownMenuItem asChild>
                                <Link href={`/projects/${project.id}`} className="flex items-center cursor-pointer">
                                    <Eye className="mr-2 h-4 w-4" /> View Details
                                </Link>
                            </DropdownMenuItem>
                        )}

                        {((hasAnyPermission(['view all projects', 'view assign projects'])) && hasAllPermissions(['view project financials','view invoices'])) && (
                            <DropdownMenuItem asChild>
                                <Link href={`/projects/${project.id}/financials/invoices`} className="flex items-center cursor-pointer">
                                    <Eye className="mr-2 h-4 w-4" /> View Invoice Page
                                </Link>
                            </DropdownMenuItem>
                        )}
                        {((hasAnyPermission(['view all projects', 'view assign projects'])) && hasAllPermissions(['view project financials','view payment received']))  && (
                            <DropdownMenuItem asChild>
                                <Link href={`/projects/${project.id}/financials/payment-received`} className="flex items-center cursor-pointer">
                                    <Eye className="mr-2 h-4 w-4" /> View Payment Received Page
                                </Link>
                            </DropdownMenuItem>
                        )}
                        {project?.businessUnit === "CBT" && ((hasAnyPermission(['view all projects', 'view assign projects'])) && hasAllPermissions(['view project financials','view vendor bill']))  && (
                            <DropdownMenuItem asChild>
                                <Link href={`/projects/${project.id}/financials/vendor-bills`} className="flex items-center cursor-pointer">
                                    <Eye className="mr-2 h-4 w-4" /> View Vendor Bills Page
                                </Link>
                            </DropdownMenuItem>
                        )}
                    </DropdownMenuContent>
                </DropdownMenu>
            );
        },
    },
    {
        accessorKey: 'id',
        header: 'Sl. No.',
        cell: ({ row }) => <div className="font-medium">{row.index + 1}</div>,
    },
    {
        accessorKey: 'categories',
        header: 'Business Unit',
        cell: ({ row }) => {
            const categories = row.original.categories;
            return categories.split('\n').map((line, index) => (
                <div key={index}>{line}</div>
            ));
        },
    },
    {
        accessorKey: 'client',
        header: 'Client',
        cell: ({ row }) => {
            const client = row.original.client;
            return <div>{client.client_name}</div>;
        },
    },
    {
        accessorKey: 'name',
        header: ({ column }) => {
            return (
                <Button
                    variant="ghost"
                    onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
                >
                    Project
                    <ArrowUpDown className="ml-2 h-4 w-4" />
                </Button>
            );
        },
        cell: ({ row }) => <Link href={`/projects/${row.original.id}`} className="font-medium flex flex-col"><div className='text-orange-600 hover:text-orange-800 hover:underline cursor-pointer'>{row.original.name}</div>{row.original.po_number !== 'N/A' && <div className='font-normal text-xs'>{row.original.po_number}</div>}</Link>,
    },
    {
        accessorKey: 'timeline',
        header: 'Timeline',
        cell: ({ row }) => <div className='flex flex-col'>
            <div className='font-medium'>{row.original.startDate} <div>{row.original.endDate && 'to ' + row.original.endDate}</div></div>
            {row.original.duration !== 0 && <div className='font-normal text-xs'>{row.original.duration} Days</div>}
        </div>,
    },
    {
        accessorKey: 'budget',
        header: 'Contract Amount',
    },
    {
        accessorKey: 'status',
        header: 'Stage',
        cell: ({ row }) => {
            const status = row.getValue('status') as string;
            const isSubmitted = row.original.is_submitted;

            if (isSubmitted !== 1) {
                return <Badge className="bg-yellow-100 text-yellow-800 hover:bg-yellow-100 border-yellow-200">Incomplete Setup</Badge>;
            }

            let className: string = "bg-yellow-200 text-yellow-800";
            if (status === 'ACTIVE' || status === 'INITIATION' || status === 'PROJECT_CREATION') className = "bg-blue-600 text-white";
            else if (status === 'COMPLETED' || status === 'COMPLETION' || status === 'PROJECT_COMPLETED') className = "bg-green-600 text-white";
            else if (status === 'NEW' || status === 'EXECUTION' || status === 'PROJECT_MANAGEMENT') className = "bg-orange-600 text-white";
            else className = "bg-red-600 text-white";

            return <Tooltip>
                <TooltipTrigger>
                    <Badge className={className}>{status}</Badge>
                </TooltipTrigger>
                <TooltipContent className='max-w-[200px]'>
                    <p>{STATUS_DETAILS.PROJECT_STATUS[
                        status as keyof typeof STATUS_DETAILS.PROJECT_STATUS
                    ]}</p>
                </TooltipContent>
            </Tooltip>
        }
    },
];

// ProjectsDataTable component removed in favor of generic DataTable
Editor is loading...
Leave a Comment