-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3200 from ever-co/develop
Release
- Loading branch information
Showing
51 changed files
with
3,859 additions
and
2,828 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react' | ||
|
||
export function CalendarView() { | ||
return ( | ||
<div className='grow h-full w-full bg-[#FFFFFF]'> | ||
|
||
</div> | ||
) | ||
} |
35 changes: 35 additions & 0 deletions
35
apps/web/app/[locale]/timesheet/components/FilterWithStatus.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React, { HTMLAttributes } from 'react'; | ||
import { Button } from 'lib/components'; | ||
import { clsxm } from '@app/utils'; | ||
|
||
export type FilterStatus = "All Tasks" | "Pending" | "Approved" | "Rejected"; | ||
export function FilterWithStatus({ | ||
activeStatus, | ||
onToggle, | ||
className | ||
}: { | ||
activeStatus: FilterStatus; | ||
onToggle: (status: FilterStatus) => void; | ||
className?: HTMLAttributes<HTMLDivElement> | ||
}) { | ||
const buttonData: { label: FilterStatus; count: number; icon: React.ReactNode }[] = [ | ||
{ label: 'All Tasks', count: 46, icon: <i className="icon-all" /> }, | ||
{ label: 'Pending', count: 12, icon: <i className="icon-pending" /> }, | ||
{ label: 'Approved', count: 28, icon: <i className="icon-approved" /> }, | ||
{ label: 'Rejected', count: 6, icon: <i className="icon-rejected" /> }, | ||
]; | ||
|
||
return ( | ||
<div className={clsxm('grid grid-cols-4 h-[2.4rem] items-center justify-start bg-[#e2e8f0aa] rounded-xl w-full', className)}> | ||
{buttonData.map(({ label, count, icon }, index) => ( | ||
<Button | ||
key={index} | ||
className={clsxm('group flex items-center justify-start h-[2.4rem] rounded-xl border dark:bg-dark--theme-light dark:border-gray-700 bg-[#e2e8f0aa] text[#71717A]', `${activeStatus === label ? "text-primary bg-white shadow-lg font-bold" : ""}`)} | ||
onClick={() => onToggle(label)}> | ||
<span className={clsxm('font-medium ml-1 text-[#71717A]', `${activeStatus === label ? "text-primary" : ""}`)}>{label}</span> | ||
<span className='font-medium ml-1 text-[#71717A]'>{count}</span> | ||
</Button> | ||
))} | ||
</div> | ||
); | ||
} |
99 changes: 99 additions & 0 deletions
99
apps/web/app/[locale]/timesheet/components/FrequencySelect.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import React from "react"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectGroup, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@components/ui/select" | ||
import { | ||
DropdownMenu, | ||
DropdownMenuContent, | ||
DropdownMenuItem, | ||
DropdownMenuPortal, | ||
DropdownMenuSub, | ||
DropdownMenuSubContent, | ||
DropdownMenuSubTrigger, | ||
DropdownMenuTrigger, | ||
} from "@components/ui/dropdown-menu" | ||
import { Button } from "lib/components/button"; | ||
|
||
export function FrequencySelect() { | ||
const [selectedValue, setSelectedValue] = React.useState<string | undefined>(undefined); | ||
|
||
const handleSelectChange = (value: string) => { | ||
setSelectedValue(value); | ||
}; | ||
|
||
return ( | ||
<Select | ||
value={selectedValue} | ||
onValueChange={handleSelectChange}> | ||
<SelectTrigger className="w-[180px] border border-gray-200 dark:border-gray-700 bg-white dark:bg-dark--theme-light focus:ring-2 focus:ring-transparent"> | ||
<SelectValue placeholder="Select a daily" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectItem value="daily">Daily</SelectItem> | ||
<SelectItem value="weekly">Weekly</SelectItem> | ||
<SelectItem value="monthly">Monthly</SelectItem> | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
); | ||
} | ||
|
||
|
||
|
||
|
||
export const FilterTaskActionMenu = () => { | ||
// const handleCopyPaymentId = () => navigator.clipboard.writeText(idTasks); | ||
return ( | ||
<DropdownMenu open={true} > | ||
<DropdownMenuTrigger asChild> | ||
<Button variant="ghost" className="h-8 w-8 p-0 text-sm sm:text-base"> | ||
{/* <span className="sr-only">Open menu</span> */} | ||
<span>Today</span> | ||
</Button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent align="end" className="z-50"> | ||
<DropdownMenuItem className="cursor-pointer" > | ||
Today | ||
</DropdownMenuItem> | ||
<DropdownMenuItem className="cursor-pointer" > | ||
Last 7 days | ||
</DropdownMenuItem> | ||
<DropdownMenuItem className="cursor-pointer" > | ||
Last 30 days | ||
</DropdownMenuItem> | ||
<DropdownMenuItem className="cursor-pointer" > | ||
This year (2024) | ||
{/* ({new Date().getFullYear()}) */} | ||
</DropdownMenuItem> | ||
{/* <DropdownMenuSeparator /> */} | ||
<CustomDateRange /> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
); | ||
}; | ||
|
||
export const CustomDateRange = () => { | ||
return ( | ||
<DropdownMenuSub> | ||
<DropdownMenuSubTrigger> | ||
<span>Custom Date Range</span> | ||
</DropdownMenuSubTrigger> | ||
<DropdownMenuPortal> | ||
<DropdownMenuSubContent> | ||
<DropdownMenuItem className="cursor-pointer"> | ||
<div className="flex items-center gap-3"> | ||
<div className="h-1 w-1 rounded-full bg-black dark:bg-white"></div> | ||
<span>Calendar</span> | ||
</div> | ||
</DropdownMenuItem> | ||
</DropdownMenuSubContent> | ||
</DropdownMenuPortal> | ||
</DropdownMenuSub> | ||
) | ||
} |
65 changes: 65 additions & 0 deletions
65
apps/web/app/[locale]/timesheet/components/TimesheetCard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
|
||
import { clsxm } from '@app/utils'; | ||
import { ArrowRightIcon } from 'assets/svg'; | ||
import { Button, Card } from 'lib/components'; | ||
import React, { ReactNode } from 'react' | ||
|
||
interface ITimesheetCard { | ||
title?: string; | ||
date?: string | ||
description?: string; | ||
hours?: string; | ||
count?: number; | ||
color?: string; | ||
icon?: ReactNode; | ||
classNameIcon?: string | ||
onClick?: () => void; | ||
} | ||
|
||
|
||
export function TimesheetCard({ ...props }: ITimesheetCard) { | ||
const { icon, title, date, description, hours, count, onClick, classNameIcon } = props; | ||
return ( | ||
<Card | ||
aria-label={`Timesheet card for ${title}`} | ||
shadow='custom' | ||
className='w-full h-[175px] rounded-md border border-gray-200 flex gap-8 shadow shadow-gray-100 p-3'> | ||
<div className='!gap-8 w-full space-y-4 '> | ||
<div className='flex flex-col gap-1 justify-start items-start'> | ||
<h1 className='text-2xl md:text-[25px] font-bold truncate w-full'>{hours ?? count}</h1> | ||
<h2 className='text-base md:text-[16px] font-medium text-[#282048] truncate w-full'>{title}</h2> | ||
<span className='text-sm md:text-[14px] text-[#3D5A80] truncate w-full'>{date ?? description}</span> | ||
</div> | ||
<Button | ||
variant='outline' | ||
className={clsxm( | ||
'h-9 px-3 py-2', | ||
'border border-gray-200', | ||
'text-[#282048] text-sm', | ||
'flex items-center', | ||
'hover:bg-gray-50 focus:ring-2 focus:ring-offset-2 focus:ring-gray-200' | ||
)} | ||
aria-label="View timesheet details" | ||
onClick={onClick}> | ||
<span>View Details</span> | ||
<ArrowRightIcon className={clsxm( | ||
'h-6 w-6', | ||
'text-[#282048] dark:text-[#6b7280]' | ||
)} /> | ||
</Button> | ||
</div> | ||
<Card | ||
shadow='custom' | ||
className={clsxm( | ||
'h-7 w-7', | ||
'flex items-center justify-center', | ||
'text-white font-bold text-sm', | ||
'shadow-lg', | ||
classNameIcon | ||
)} | ||
aria-hidden="true"> | ||
{icon} | ||
</Card> | ||
</Card> | ||
) | ||
} |
39 changes: 39 additions & 0 deletions
39
apps/web/app/[locale]/timesheet/components/TimesheetFilter.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React from 'react' | ||
import { FilterWithStatus } from './FilterWithStatus' | ||
import { FrequencySelect } from '.'; | ||
import { Button } from 'lib/components'; | ||
import { SettingFilterIcon } from 'assets/svg'; | ||
|
||
export function TimesheetFilter() { | ||
return ( | ||
<div className="grid grid-cols-3 w-full"> | ||
<div className="col-span-1"> | ||
<FilterWithStatus | ||
activeStatus="Rejected" | ||
onToggle={(label) => { | ||
console.log(label) | ||
}} | ||
/> | ||
</div> | ||
<div className="col-span-1"></div> | ||
<div className="col-span-1"> | ||
<div className='flex gap-2'> | ||
<FrequencySelect /> | ||
<button | ||
onClick={() => null} | ||
className='flex items-center justify-center h-10 rounded-lg bg-white dark:bg-dark--theme-light border dark:border-gray-700 hover:bg-white p-3 gap-2' > | ||
<SettingFilterIcon className="text-gray-700 dark:text-white w-3.5" strokeWidth="1.8" /> | ||
<span className="text-gray-700 dark:text-white">Filter</span> | ||
</button> | ||
<Button | ||
onClick={() => null} | ||
variant='outline' | ||
className='bg-primary/5 dark:bg-primary-light h-10 w-[2.5rem] font-medium'> | ||
Add Time | ||
</Button> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
) | ||
} |
Oops, something went wrong.