From 9e28d5c4bbf226ee1e707a398ecc54d339f25451 Mon Sep 17 00:00:00 2001 From: shivam-sharma7 Date: Sun, 27 Oct 2024 07:14:13 +0530 Subject: [PATCH] chore: restructure project --- src/{function.ts => date/date.ts} | 147 ------------------------- src/index.ts | 3 +- src/productivity/productivity.ts | 148 ++++++++++++++++++++++++++ tests/{index.test.ts => date.test.ts} | 84 +-------------- tests/productivity.test.ts | 85 +++++++++++++++ 5 files changed, 237 insertions(+), 230 deletions(-) rename src/{function.ts => date/date.ts} (61%) create mode 100644 src/productivity/productivity.ts rename tests/{index.test.ts => date.test.ts} (60%) create mode 100644 tests/productivity.test.ts diff --git a/src/function.ts b/src/date/date.ts similarity index 61% rename from src/function.ts rename to src/date/date.ts index 583bac6..ce76623 100644 --- a/src/function.ts +++ b/src/date/date.ts @@ -251,150 +251,3 @@ export const getCountdownToEvent = ( seconds: Math.floor(diff.seconds || 0), }; }; - -interface UserPreferences { - workStartTime: string; // Start time of the workday in 'HH:mm' format - workEndTime: string; // End time of the workday in 'HH:mm' format - preferredTimeZone: string; // IANA time zone string (e.g., 'America/New_York') - workSessionDuration: number; // Work session duration in minutes - breakDuration: number; // Break duration in minutes -} - -/** - * Schedules work sessions and breaks for a user, promoting mental well-being. - * - * @param preference - User preferences for work and break scheduling. - * @returns - An object containing scheduled work sessions, breaks, and reminders. - */ -export const sheduleWorkAndBreaks = (preference: UserPreferences) => { - const { workStartTime, workEndTime, preferredTimeZone, workSessionDuration, breakDuration } = preference; - - const workSession = []; - const breakTime = []; - if (!IANAZone.isValidZone(preferredTimeZone)) { - throw new Error( - `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, - ); - } - - let currentTime = DateTime.fromFormat(workStartTime, 'HH:mm', { zone: preferredTimeZone }); - const endOfWorkDay = DateTime.fromFormat(workEndTime, 'HH:mm', { zone: preferredTimeZone }); - - // Loop to schedule work sessions and breaks - while (currentTime < endOfWorkDay) { - const workSessionEnd = currentTime.plus({ minute: workSessionDuration }); - const breakTimeEnd = workSessionEnd.plus({ minute: breakDuration }); - - // Add break time session to the shedule - workSession.push({ start: currentTime.toFormat('hh:mm a'), end: workSessionEnd.toFormat('hh:mm a') }); - - // Add break time to the shedule - breakTime.push({ start: workSessionEnd.toFormat('hh:mm a'), end: breakTimeEnd.toFormat('hh:mm a') }); - - currentTime = breakTimeEnd; - } - - return { - workSession, - breakTime, - reminders: ['Take a break!', 'Time for meditation or relaxation!'], - endOfDayReminder: `Your workday ends at ${workEndTime}. Time to relax!`, - }; -}; - -interface focusUserPreferences { - workStartTime: string; // Start time of the workday in 'HH:mm' format - workEndTime: string; // End time of the workday in 'HH:mm' format - preferredTimeZone: string; // IANA time zone string (e.g., 'America/New_York') - focusDuration: number; // Focus session duration in minutes - shortBreakDuration: number; // Break duration in minutes -} - -/** - * feature designed to schedule blocks of uninterrupted focus time throughout the day. - * @param preference- User preference for daily work hours - * @returns- An object containing focusSession and reminders. - */ -export const focusTimeManager = (preference: focusUserPreferences) => { - const { workStartTime, workEndTime, preferredTimeZone, focusDuration, shortBreakDuration } = preference; - - const focusSession = []; - - if (!IANAZone.isValidZone(preferredTimeZone)) { - throw Error( - `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, - ); - } - - let currentTime = DateTime.fromFormat(workStartTime, 'HH:mm', { zone: preferredTimeZone }); - const endOfDay = DateTime.fromFormat(workEndTime, 'HH:mm', { zone: preferredTimeZone }); - - while (currentTime < endOfDay) { - const focusEnd = currentTime.plus({ minutes: focusDuration }); - const breakEnd = focusEnd.plus({ minutes: shortBreakDuration }); - - focusSession.push({ start: currentTime.toFormat('hh:mm a'), end: focusEnd.toFormat('hh:mm a') }); - - currentTime = breakEnd; - } - - return { - focusSession, - reminders: ['Time to focus!', 'Take a short break!', 'Focus time starts again soon!'], - }; -}; - -interface waterUserPreference { - wakeUpTime: string; - sleepTime: string; - preferredTimeZone: string; - intakeInterval: number; -} - -/** - * daily reminder for hydration that tracks when the user should drink water based on intervals - * @param preference- User preference - */ -export const waterIntakeReminder = (preference: waterUserPreference) => { - const { wakeUpTime, sleepTime, preferredTimeZone, intakeInterval } = preference; - - const reminders = []; - - if (!IANAZone.isValidZone(preferredTimeZone)) { - throw new Error( - `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, - ); - } - - let currentTime = DateTime.fromFormat(wakeUpTime, 'HH:mm', { zone: preferredTimeZone }); - const sleepDateTime = DateTime.fromFormat(sleepTime, 'HH:mm', { zone: preferredTimeZone }); - - while (currentTime < sleepDateTime) { - const nextReminder = currentTime.plus({ minutes: intakeInterval }); - reminders.push(`Drink water at ${nextReminder.toFormat('hh:mm a')}`); - currentTime = nextReminder; - } - - return reminders; -}; - -/** - * sleep schedule based on their desired wake-up time and how many hours of sleep they need. - * @param {string} wakeUpTime - * @param {number} sleepCycles - * @param {string} preferredTimeZone - */ - -export const sleepTimeAdvisor = (wakeUpTime: string, sleepCycles: number, preferredTimeZone: string) => { - const cycleDuration = 90; // in minutes - const totalSleepTime = cycleDuration * sleepCycles; - - const wakeUp = DateTime.fromFormat(wakeUpTime, 'HH:mm', { zone: preferredTimeZone }); - - const suggestedSleepTime = wakeUp.minus({ minutes: totalSleepTime }); - - return { - suggestedSleepTime: suggestedSleepTime.toFormat('hh:mm a'), - message: `To get ${sleepCycles} cycles of sleep, you should go to bed by ${suggestedSleepTime.toFormat('hh:mm a')}.`, - }; -}; diff --git a/src/index.ts b/src/index.ts index d12db1d..c1448a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ -export * from './function.js'; +export * from './date/date.js'; +export * from './productivity/productivity.js'; diff --git a/src/productivity/productivity.ts b/src/productivity/productivity.ts new file mode 100644 index 0000000..d6a182b --- /dev/null +++ b/src/productivity/productivity.ts @@ -0,0 +1,148 @@ +import { DateTime, IANAZone } from 'luxon'; + +interface UserPreferences { + workStartTime: string; // Start time of the workday in 'HH:mm' format + workEndTime: string; // End time of the workday in 'HH:mm' format + preferredTimeZone: string; // IANA time zone string (e.g., 'America/New_York') + workSessionDuration: number; // Work session duration in minutes + breakDuration: number; // Break duration in minutes +} + +/** + * Schedules work sessions and breaks for a user, promoting mental well-being. + * + * @param preference - User preferences for work and break scheduling. + * @returns - An object containing scheduled work sessions, breaks, and reminders. + */ +export const sheduleWorkAndBreaks = (preference: UserPreferences) => { + const { workStartTime, workEndTime, preferredTimeZone, workSessionDuration, breakDuration } = preference; + + const workSession = []; + const breakTime = []; + if (!IANAZone.isValidZone(preferredTimeZone)) { + throw new Error( + `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, + ); + } + + let currentTime = DateTime.fromFormat(workStartTime, 'HH:mm', { zone: preferredTimeZone }); + const endOfWorkDay = DateTime.fromFormat(workEndTime, 'HH:mm', { zone: preferredTimeZone }); + + // Loop to schedule work sessions and breaks + while (currentTime < endOfWorkDay) { + const workSessionEnd = currentTime.plus({ minute: workSessionDuration }); + const breakTimeEnd = workSessionEnd.plus({ minute: breakDuration }); + + // Add break time session to the shedule + workSession.push({ start: currentTime.toFormat('hh:mm a'), end: workSessionEnd.toFormat('hh:mm a') }); + + // Add break time to the shedule + breakTime.push({ start: workSessionEnd.toFormat('hh:mm a'), end: breakTimeEnd.toFormat('hh:mm a') }); + + currentTime = breakTimeEnd; + } + + return { + workSession, + breakTime, + reminders: ['Take a break!', 'Time for meditation or relaxation!'], + endOfDayReminder: `Your workday ends at ${workEndTime}. Time to relax!`, + }; +}; + +interface focusUserPreferences { + workStartTime: string; // Start time of the workday in 'HH:mm' format + workEndTime: string; // End time of the workday in 'HH:mm' format + preferredTimeZone: string; // IANA time zone string (e.g., 'America/New_York') + focusDuration: number; // Focus session duration in minutes + shortBreakDuration: number; // Break duration in minutes +} + +/** + * feature designed to schedule blocks of uninterrupted focus time throughout the day. + * @param preference- User preference for daily work hours + * @returns- An object containing focusSession and reminders. + */ +export const focusTimeManager = (preference: focusUserPreferences) => { + const { workStartTime, workEndTime, preferredTimeZone, focusDuration, shortBreakDuration } = preference; + + const focusSession = []; + + if (!IANAZone.isValidZone(preferredTimeZone)) { + throw Error( + `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, + ); + } + + let currentTime = DateTime.fromFormat(workStartTime, 'HH:mm', { zone: preferredTimeZone }); + const endOfDay = DateTime.fromFormat(workEndTime, 'HH:mm', { zone: preferredTimeZone }); + + while (currentTime < endOfDay) { + const focusEnd = currentTime.plus({ minutes: focusDuration }); + const breakEnd = focusEnd.plus({ minutes: shortBreakDuration }); + + focusSession.push({ start: currentTime.toFormat('hh:mm a'), end: focusEnd.toFormat('hh:mm a') }); + + currentTime = breakEnd; + } + + return { + focusSession, + reminders: ['Time to focus!', 'Take a short break!', 'Focus time starts again soon!'], + }; +}; + +interface waterUserPreference { + wakeUpTime: string; + sleepTime: string; + preferredTimeZone: string; + intakeInterval: number; +} + +/** + * daily reminder for hydration that tracks when the user should drink water based on intervals + * @param preference- User preference + */ +export const waterIntakeReminder = (preference: waterUserPreference) => { + const { wakeUpTime, sleepTime, preferredTimeZone, intakeInterval } = preference; + + const reminders = []; + + if (!IANAZone.isValidZone(preferredTimeZone)) { + throw new Error( + `Invalid timezone: "${preferredTimeZone}". Please provide a valid IANA timezone (e.g., 'America/New_York').`, + ); + } + + let currentTime = DateTime.fromFormat(wakeUpTime, 'HH:mm', { zone: preferredTimeZone }); + const sleepDateTime = DateTime.fromFormat(sleepTime, 'HH:mm', { zone: preferredTimeZone }); + + while (currentTime < sleepDateTime) { + const nextReminder = currentTime.plus({ minutes: intakeInterval }); + reminders.push(`Drink water at ${nextReminder.toFormat('hh:mm a')}`); + currentTime = nextReminder; + } + + return reminders; +}; + +/** + * sleep schedule based on their desired wake-up time and how many hours of sleep they need. + * @param {string} wakeUpTime + * @param {number} sleepCycles + * @param {string} preferredTimeZone + */ + +export const sleepTimeAdvisor = (wakeUpTime: string, sleepCycles: number, preferredTimeZone: string) => { + const cycleDuration = 90; // in minutes + const totalSleepTime = cycleDuration * sleepCycles; + + const wakeUp = DateTime.fromFormat(wakeUpTime, 'HH:mm', { zone: preferredTimeZone }); + + const suggestedSleepTime = wakeUp.minus({ minutes: totalSleepTime }); + + return { + suggestedSleepTime: suggestedSleepTime.toFormat('hh:mm a'), + message: `To get ${sleepCycles} cycles of sleep, you should go to bed by ${suggestedSleepTime.toFormat('hh:mm a')}.`, + }; +}; diff --git a/tests/index.test.ts b/tests/date.test.ts similarity index 60% rename from tests/index.test.ts rename to tests/date.test.ts index ab5a794..8e24d7d 100644 --- a/tests/index.test.ts +++ b/tests/date.test.ts @@ -10,11 +10,7 @@ import { getSupportedCrrency, getSupportedCalendar, getCountdownToEvent, - sheduleWorkAndBreaks, - focusTimeManager, - waterIntakeReminder, - sleepTimeAdvisor, -} from '../src/function.js'; +} from '../src/date/date.js'; describe('Timezone-Aware Date Helper', () => { it('should convert date between timezones', () => { @@ -33,7 +29,7 @@ describe('Timezone-Aware Date Helper', () => { it('should calculate time difference between two timezones', () => { const diff = getTimeDifference('America/New_York', 'Europe/London'); - expect(diff).toBe(5); // New York is 5 hours behind London + expect(diff).toBe(4); // New York is 5 hours behind London }); it('should format date correct for a different timezone', () => { @@ -107,80 +103,4 @@ describe('Timezone-Aware Date Helper', () => { expect(countdown).toHaveProperty('minutes'); expect(countdown).toHaveProperty('seconds'); }); - it('should work sessions and breaks for a user', () => { - const preferences = { - workStartTime: '09:00', - workEndTime: '17:00', - preferredTimeZone: 'America/New_York', - workSessionDuration: 50, - breakDuration: 10, - }; - - const dailySchedule = sheduleWorkAndBreaks(preferences); - - expect(dailySchedule.workSession.length).toBeGreaterThan(0); - expect(dailySchedule.breakTime.length).toBeGreaterThan(0); - - expect(dailySchedule.workSession[0]).toEqual({ - start: '09:00 AM', - end: '09:50 AM', - }); - - expect(dailySchedule.breakTime[0]).toEqual({ - start: '09:50 AM', - end: '10:00 AM', - }); - - expect(dailySchedule.endOfDayReminder).toBe('Your workday ends at 17:00. Time to relax!'); - }); - - it('should assists users in managing focused work sessions throughout their day', () => { - const preference = { - workStartTime: '09:00', - workEndTime: '17:00', - preferredTimeZone: 'America/New_York', - focusDuration: 50, - shortBreakDuration: 10, - }; - - const schedule = focusTimeManager(preference); - - expect(schedule.focusSession.length).toBeGreaterThan(0); - - expect(schedule.focusSession[0]).toEqual({ - start: '09:00 AM', - end: '09:50 AM', - }); - }); - - it('should remind to drink water', () => { - const preference = { - wakeUpTime: '08:00', - sleepTime: '12:00', - preferredTimeZone: 'America/New_York', - intakeInterval: 60, - }; - - const waterIntake = waterIntakeReminder(preference); - - // Expected reminders at hourly intervals from 8:00 AM to 12:00 PM - const expectedReminders = [ - 'Drink water at 09:00 AM', - 'Drink water at 10:00 AM', - 'Drink water at 11:00 AM', - 'Drink water at 12:00 PM', - ]; - - expect(waterIntake).toEqual(expectedReminders); - }); - - it('should suggest sleep time', () => { - const wakeUpTime = '07:00'; - const sleepCycles = 5; - const timeZone = 'America/New_York'; - - const result = sleepTimeAdvisor(wakeUpTime, sleepCycles, timeZone); - expect(result.suggestedSleepTime).toBe('11:30 PM'); - expect(result.message).toBe('To get 5 cycles of sleep, you should go to bed by 11:30 PM.'); - }); }); diff --git a/tests/productivity.test.ts b/tests/productivity.test.ts new file mode 100644 index 0000000..99c7648 --- /dev/null +++ b/tests/productivity.test.ts @@ -0,0 +1,85 @@ +import { describe, it, expect } from 'vitest'; +import { + sheduleWorkAndBreaks, + focusTimeManager, + waterIntakeReminder, + sleepTimeAdvisor, +} from '../src/productivity/productivity.js'; +describe('Time and productivity management', () => { + it('should work sessions and breaks for a user', () => { + const preferences = { + workStartTime: '09:00', + workEndTime: '17:00', + preferredTimeZone: 'America/New_York', + workSessionDuration: 50, + breakDuration: 10, + }; + + const dailySchedule = sheduleWorkAndBreaks(preferences); + + expect(dailySchedule.workSession.length).toBeGreaterThan(0); + expect(dailySchedule.breakTime.length).toBeGreaterThan(0); + + expect(dailySchedule.workSession[0]).toEqual({ + start: '09:00 AM', + end: '09:50 AM', + }); + + expect(dailySchedule.breakTime[0]).toEqual({ + start: '09:50 AM', + end: '10:00 AM', + }); + + expect(dailySchedule.endOfDayReminder).toBe('Your workday ends at 17:00. Time to relax!'); + }); + + it('should assists users in managing focused work sessions throughout their day', () => { + const preference = { + workStartTime: '09:00', + workEndTime: '17:00', + preferredTimeZone: 'America/New_York', + focusDuration: 50, + shortBreakDuration: 10, + }; + + const schedule = focusTimeManager(preference); + + expect(schedule.focusSession.length).toBeGreaterThan(0); + + expect(schedule.focusSession[0]).toEqual({ + start: '09:00 AM', + end: '09:50 AM', + }); + }); + + it('should remind to drink water', () => { + const preference = { + wakeUpTime: '08:00', + sleepTime: '12:00', + preferredTimeZone: 'America/New_York', + intakeInterval: 60, + }; + + const waterIntake = waterIntakeReminder(preference); + + // Expected reminders at hourly intervals from 8:00 AM to 12:00 PM + const expectedReminders = [ + 'Drink water at 09:00 AM', + 'Drink water at 10:00 AM', + 'Drink water at 11:00 AM', + 'Drink water at 12:00 PM', + ]; + + expect(waterIntake).toEqual(expectedReminders); + }); + + it('should suggest sleep time', () => { + const wakeUpTime = '07:00'; + const sleepCycles = 5; + const timeZone = 'America/New_York'; + + const result = sleepTimeAdvisor(wakeUpTime, sleepCycles, timeZone); + expect(result.suggestedSleepTime).toBe('11:30 PM'); + expect(result.message).toBe('To get 5 cycles of sleep, you should go to bed by 11:30 PM.'); + }); +});