Skip to content

Commit

Permalink
Merge pull request #2879 from ever-co/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Aug 10, 2024
2 parents e319fe0 + c71472a commit 85dfd3e
Show file tree
Hide file tree
Showing 19 changed files with 285 additions and 160 deletions.
82 changes: 68 additions & 14 deletions apps/web/lib/features/daily-plan/create-daily-plan-form-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { ScrollArea } from '@components/ui/scroll-bar';
import { clsxm, isValidUrl } from '@app/utils';
import stc from 'string-to-color';
import { Check } from 'lucide-react';
import { cn } from 'lib/utils';
import { MdOutlineKeyboardArrowDown } from 'react-icons/md';

export function CreateDailyPlanFormModal({
open,
Expand Down Expand Up @@ -46,11 +48,24 @@ export function CreateDailyPlanFormModal({

const [date, setDate] = useState<Date>(new Date(tomorrowDate));
const [selectedEmployee, setSelectedEmployee] = useState<OT_Member | undefined>(isManagerConnectedUser);
const [isOpen, setIsOpen] = useState(false);

const handleMemberClick = useCallback((member: OT_Member) => {
setSelectedEmployee(member);
}, []);

const handleCloseModal = useCallback(() => {
closeModal();
}, [closeModal]);

const handleSelect = useCallback(() => {
reset();
}, [reset]);

const handleSelectAndClose = useCallback(() => {
handleCloseModal();
}, [handleCloseModal]);

const onSubmit = useCallback(
async (values: any) => {
const toDay = new Date();
Expand All @@ -69,7 +84,6 @@ export function CreateDailyPlanFormModal({
organizationId: user?.employee.organizationId
}).then(() => {
reset();
closeModal();
});
},
[
Expand All @@ -81,20 +95,19 @@ export function CreateDailyPlanFormModal({
user?.employee.organizationId,
employeeId,
selectedEmployee?.employeeId,
reset,
closeModal
reset
]
);

return (
<Modal isOpen={open} closeModal={closeModal}>
<Modal isOpen={open} closeModal={handleCloseModal}>
<form className="w-[98%] md:w-[430px] relative" autoComplete="off" onSubmit={handleSubmit(onSubmit)}>
<Card className="w-full" shadow="custom">
<div className="flex flex-col items-center justify-between">
{/* Form header */}
<div className="mb-3">
<Text.Heading as="h3" className="text-start">
Plan this task for {moment(date).format('DD.MM.YYYY').toString()}
Select Date
</Text.Heading>
</div>

Expand Down Expand Up @@ -135,15 +148,56 @@ export function CreateDailyPlanFormModal({
>
Cancel
</Button>
<Button
variant="default"
type="submit"
className="px-7 py-4 font-normal rounded-xl text-md"
disabled={createDailyPlanLoading}
>
{createDailyPlanLoading && <ReloadIcon className="animate-spin mr-2 h-4 w-4" />}
{planMode === 'custom' ? 'Select Date' : 'Create Plan'}
</Button>
<div className="relative w-40 inline-block text-left">
<Button
type="button"
className={clsxm(
'font-normal flex items-center justify-between w-full rounded-xl text-md',
createDailyPlanLoading ? 'justify-center' : 'justify-between'
)}
onClick={() => setIsOpen(!isOpen)}
>
{createDailyPlanLoading ? (
<ReloadIcon className="animate-spin mr-2 h-4 w-4" />
) : (
<>
<span>Select date</span>
<MdOutlineKeyboardArrowDown
className={cn(
'h-6 w-6 transition-transform',
isOpen && 'rotate-180'
)}
/>
</>
)}
</Button>
{isOpen && (
<div className="absolute right-0 w-full mt-2 p-2 origin-top-right bg-white divide-y divide-gray-100 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="flex w-full flex-col items-center gap-1">
<Button
disabled={createDailyPlanLoading}
onClick={handleSelect}
size="sm"
variant="outline"
type="submit"
className="w-full text-xs"
>
Select
</Button>
<Button
disabled={createDailyPlanLoading}
onClick={handleSelectAndClose}
size="sm"
variant="outline"
type="submit"
className="w-full text-xs"
>
Select & Close
</Button>
</div>
</div>
)}
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function SuggestDailyPlanModal(props: ISuggestDailyPlanModalProps) {
}, [closeModal, currentDate]);

return (
<Modal isOpen={isOpen} closeModal={handleCloseModal}>
<Modal isOpen={isOpen} closeModal={handleCloseModal} showCloseIcon={false}>
<Card className="w-full" shadow="custom">
<div className="flex flex-col items-center justify-between">
<div className="mb-7">
Expand Down
128 changes: 77 additions & 51 deletions apps/web/lib/features/integrations/activity-calendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect, useState } from 'react';
import { CalendarDatum, ResponsiveCalendar } from '@nivo/calendar';
import Skeleton from 'react-loading-skeleton';
import moment from 'moment';
import Separator from '@components/ui/separator';

export function ActivityCalendar() {
const { timerLogsDailyReport, timerLogsDailyReportLoading } = useTimeLogs();
Expand All @@ -15,48 +16,69 @@ export function ActivityCalendar() {
);
}, [timerLogsDailyReport]);

const colorRange = [
'#9370DB',
'#6A5ACD',
'#4169E1',
'#0000FF',
'#1E90FF',
'#87CEEB',
'#FFA500',
'#FF8C00',
'#FF4500',
'#FF0000'
];

return (
<div className=" h-[650px] w-full flex items-center justify-center overflow-y-hidden overflow-x-auto">
<div className="h-[650px] w-full flex items-center justify-center overflow-y-hidden overflow-x-auto">
{timerLogsDailyReportLoading ? (
<ActivityCalendarSkeleton />
) : (
<div className='flex flex-col w-full h-full relative'>
<div className='flex flex-col w-full h-full'>
<ActivityLegend />
<ResponsiveCalendar
data={calendarData}
from={moment().startOf('year').toDate()}
to={moment().startOf('year').toDate()}
emptyColor="#ffffff"
colors={['#ADD8E6', '#9370DB', '#6A5ACD', '#0000FF']}
yearSpacing={40}
monthBorderWidth={0}
dayBorderWidth={0}
daySpacing={2}
monthLegendPosition="before"
margin={{ top: 10, right: 5, bottom: 10, left: 5 }}
legends={[
{
anchor: 'bottom-right',
direction: 'row',
translateY: 36,
itemCount: 3,
itemWidth: 42,
itemHeight: 36,
itemsSpacing: 14,
itemDirection: 'right-to-left',
data: [
{ color: '#0000FF', label: '8 hours or more', id: 'legend-blue' },
{ color: '#6A5ACD', label: '6 hours', id: 'legend-slateblue' },
{ color: '#9370DB', label: '4 hours', id: 'legend-purple' },
{ color: '#ADD8E6', label: '2 hours', id: 'legend-light-blue' }
]
}
]}
monthSpacing={20}
monthLegend={(_, __, d) => d.toLocaleString('en-US', { month: 'short' })}
/>


<div className='h-80 w-full'>
<ResponsiveCalendar
tooltip={(value) => (
<div className="flex items-center mb-2">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: value.color }}></span>
<span className={`text-[14px] font-semibold dark:!text-primary-xlight`}>{value.day}</span>
</div>
)}
yearLegend={(value) => value}
data={calendarData}
from={moment().startOf('year').toDate()}
to={moment().startOf('year').toDate()}
emptyColor="#ffffff"
colors={colorRange}
yearSpacing={40}
monthBorderWidth={0}
dayBorderWidth={0}
daySpacing={2}
monthLegendPosition="before"
margin={{ top: 0, right: 5, bottom: 0, left: 5 }}
legends={[
{
anchor: 'bottom-right',
direction: 'row',
translateY: 36,
itemCount: 4,
itemWidth: 70,
itemHeight: 20,
itemsSpacing: 14,
itemDirection: 'left-to-right',
symbolSize: 20,
data: [
{ color: '#9370DB', label: '0 - 4 Hours', id: 'legend-purple' },
{ color: '#0000FF', label: '4 - 10 Hours', id: 'legend-blue' },
{ color: '#FFA500', label: '10 - 18 Hours', id: 'legend-orange' },
{ color: '#FF0000', label: '18 - 24 Hours', id: 'legend-red' }
]
}
]}
monthSpacing={20}
monthLegend={(_, __, d) => d.toLocaleString('en-US', { month: 'short' })}
/>
</div>
</div>
)}
</div>
Expand Down Expand Up @@ -84,24 +106,28 @@ function ActivityCalendarSkeleton() {

function ActivityLegend() {
return (
<div className="flex flex-col w-full items-start p-4 bg-white dark:bg-dark--theme-light rounded-lg shadow-sm">
<div className="flex w-full items-center justify-start p-1 bg-white dark:bg-dark--theme-light rounded-lg shadow shadow-slate-50 dark:shadow-slate-700 space-x-3 px-3">
<h3 className="text-lg font-bold mb-2">Legend</h3>
<div className="flex items-center mb-2" id="legend-blue">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#0000FF' }}></span>
<span>8 Hours or more</span>
<Separator />
<div className="flex items-center" id="legend-purple">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#9370DB' }}></span>
<span>0 - 4 Hours</span>
</div>
<div className="flex items-center mb-2" id="legend-slateblue">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#6A5ACD' }}></span>
<span>6 Hours</span>
<Separator />
<div className="flex items-center" id="legend-blue">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#0000FF' }}></span>
<span>4 - 10 Hours</span>
</div>
<div className="flex items-center mb-2" id="legend-purple">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#9370DB' }}></span>
<span>4 Hours</span>
<Separator />
<div className="flex items-center" id="legend-orange">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#FFA500' }}></span>
<span>10 - 18 Hours</span>
</div>
<div className="flex items-center mb-2" id="legend-light-blue">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#ADD8E6' }}></span>
<span>2 Hours</span>
<Separator />
<div className="flex items-center" id="legend-red">
<span className="w-4 h-4 inline-block mr-2" style={{ backgroundColor: '#FF0000' }}></span>
<span>18 - 24 Hours</span>
</div>
</div>
)
);
}
51 changes: 22 additions & 29 deletions apps/web/lib/features/task/task-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -537,13 +537,14 @@ function TaskCardMenu({
);

const allPlans = [...todayPlan, ...futurePlans];
const isTaskPlannedMultipleTimes = allPlans.reduce((count, plan) => {
if (plan?.tasks) {
const taskCount = plan.tasks.filter(_task => _task.id === task.id).length;
return count + taskCount;
}
return count;
}, 0) > 1;
const isTaskPlannedMultipleTimes =
allPlans.reduce((count, plan) => {
if (plan?.tasks) {
const taskCount = plan.tasks.filter((_task) => _task.id === task.id).length;
return count + taskCount;
}
return count;
}, 0) > 1;

const taskPlannedTomorrow = useMemo(
() =>
Expand Down Expand Up @@ -604,7 +605,8 @@ function TaskCardMenu({
</span>
</li>

{viewType == 'default' && (
{(viewType == 'default' ||
(viewType === 'dailyplan' && planMode === 'Outstanding')) && (
<>
<Divider type="HORIZONTAL" />
<div className="mt-3">
Expand Down Expand Up @@ -638,16 +640,6 @@ function TaskCardMenu({
</>
)}

{viewType === 'dailyplan' && planMode === 'Outstanding' && (
<>
{canSeeActivity ? (
<AddTaskToPlanComponent employee={profile?.member} task={task} />
) : (
<></>
)}
</>
)}

{viewType === 'dailyplan' &&
(planMode === 'Today Tasks' || planMode === 'Future Tasks') && (
<>
Expand All @@ -667,7 +659,8 @@ function TaskCardMenu({
task={task}
member={profile?.member}
/>
</div>)}
</div>
)}
</div>
) : (
<></>
Expand Down Expand Up @@ -753,7 +746,15 @@ export function PlanTask({
};

return (
<>
<div>
<CreateDailyPlanFormModal
open={isOpen}
closeModal={closeModal}
taskId={taskId}
planMode={planMode}
employeeId={employeeId}
chooseMember={chooseMember}
/>
<button
className={clsxm(
'font-normal whitespace-nowrap transition-all',
Expand All @@ -762,14 +763,6 @@ export function PlanTask({
onClick={handleOpenModal}
disabled={planMode === 'today' && createDailyPlanLoading}
>
<CreateDailyPlanFormModal
open={isOpen}
closeModal={closeModal}
taskId={taskId}
planMode={planMode}
employeeId={employeeId}
chooseMember={chooseMember}
/>
{planMode === 'today' && !taskPlannedToday && (
<span className="">
{isPending || createDailyPlanLoading ? (
Expand All @@ -790,7 +783,7 @@ export function PlanTask({
)}
{planMode === 'custom' && t('dailyPlan.PLAN_FOR_SOME_DAY')}
</button>
</>
</div>
);
}

Expand Down
Loading

0 comments on commit 85dfd3e

Please sign in to comment.