diff --git a/src/assets/ChromeSetup.exe b/src/assets/ChromeSetup.exe new file mode 100644 index 0000000..0b6a558 Binary files /dev/null and b/src/assets/ChromeSetup.exe differ diff --git a/src/assets/approvals-banner.png b/src/assets/approvals-banner.png new file mode 100644 index 0000000..2c5bbb3 Binary files /dev/null and b/src/assets/approvals-banner.png differ diff --git a/src/assets/event-banner.png b/src/assets/event-banner.png new file mode 100644 index 0000000..801ed06 Binary files /dev/null and b/src/assets/event-banner.png differ diff --git a/src/assets/targo-default-avatar.png b/src/assets/targo-default-avatar.png new file mode 100644 index 0000000..1893831 Binary files /dev/null and b/src/assets/targo-default-avatar.png differ diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 20978f3..6011d76 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -13,15 +13,18 @@ // Tip: Use the "Theme Builder" on Quasar's documentation website. $primary: #019547; -$secondary: #EFFFEF; -$accent: #4ada86; +$secondary: #DAE0E7; +$accent: #AAD5C4; -$dark-font: #305530; -$dark: #323232; +$verdigris: #6EBAB0; +$mint: #56B586; + +$dark-font: #1f3a1f; +$dark: #000; $dark-page: #323232; $positive: #21ba45; -$negative: #c10015; +$negative: #ff586c71; $info: #31ccec; -$warning: #eeb10a; +$warning: #ffde82c2; $white: white; diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index 0abf782..fce462c 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -23,6 +23,7 @@ export default { clearFilter: 'Clear filter', }, navBar: { + userMenuHome: 'Homepage', userMenuEmployeeList: 'Employee list', userMenuShiftValidation: 'Timesheet Approval', userMenuProfile: 'Profile', @@ -32,8 +33,8 @@ export default { userMenuCalendar: 'Calendar', }, notFoundPage: { - pageTitle: 'Oops. Nothing here...', - backButton: 'Go to the home page', + pageText: 'We cannot seem to find the page you are looking for, sorry!', + backButton: 'Take me back!', }, loginPage: { title: 'Log in to Targo', @@ -292,23 +293,21 @@ export default { }, timeSheetValidations: { tableHeader: 'List of employees', - tableCol_1: 'Full name', - tableCol_2: 'Regular hours', - tableCol_3: 'Evening hours', - tableCol_4: 'Emergency hours', - tableCol_5: 'Overtime hours', - tableCol_6: 'Expenses', - tableCol_7: 'Mileage', - tableCol_8: 'Status', - tableCol_9: 'Supervisor', + tableColumnLabelFullname: 'Full name', + tableColumnLabelRegularHours: 'regular hours', + tableColumnLabelEveningHours: 'evening hours', + tableColumnLabelEmergencyHours: 'emergency hours', + tableColumnLabelOvertime: 'overtime hours', + tableColumnLabelExpenses: 'of expenses', + tableColumnLabelMileage: 'of mileage', actionTitle: 'Please save the changes made.', actionButton: 'Save', - timeSheetStatus_verified: 'Verified', - timeSheetStatus_unverified: 'Unverified', - timeSheetStatus_partial: 'Partial', - timeSheetStatus_complete: 'Complete', - timeSheetStatus_empty: 'Empty', - timeSheetStatus_blocked: 'Blocked', + timeSheetStatusVerified: 'approved', + timeSheetStatusUnverified: 'pending', + timeSheetStatusPartial: 'partially approved', + timeSheetStatusComplete: 'complete', + timeSheetStatusEmpty: 'empty', + timeSheetStatusBlocked: 'blocked', showAllCheckbox: 'Show all', accumulatedSicknessTotal: 'Accumulated illnesses', consumedSicknessTotal: 'Consumed with illnesses', diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index b3b61f9..7f9db97 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -162,6 +162,7 @@ export default { clearFilter: 'Effacer le filtre', }, navBar: { + userMenuHome: 'Accueil', userMenuEmployeeList: 'Liste employés', userMenuShiftValidation: 'Valider les heures', userMenuProfile: 'Profil', @@ -171,8 +172,8 @@ export default { userMenuCalendar: 'Calendrier annuel', }, notFoundPage: { - pageTitle: 'Oops. Rien ici...', - backButton: 'Aller à la page d’accueil', + pageText: 'On ne semble pas trouver la page que vous cherchez, désolé!', + backButton: 'Je veux retourner en arrière!', }, notificationDialog: { notice: 'Notification', @@ -338,23 +339,21 @@ export default { }, timeSheetValidations: { tableHeader: 'Liste des employés', - tableCol_1: 'Nom et prénom', - tableCol_2: 'Heures régulières', - tableCol_3: 'Heures de soir', - tableCol_4: 'Heures d’urgence', - tableCol_5: 'Heures supplémentaires', - tableCol_6: 'Dépenses ', - tableCol_7: 'Kilométrage ', - tableCol_8: 'État', - tableCol_9: 'Superviseur', + tableColumnLabelFullname: 'nom complet', + tableColumnLabelRegularHours: 'heures régulières', + tableColumnLabelEveningHours: 'heures de soir', + tableColumnLabelEmergencyHours: 'heures d’urgence', + tableColumnLabelOvertime: 'heures supplémentaires', + tableColumnLabelExpenses: 'de dépenses', + tableColumnLabelMileage: 'de kilométrage', actionTitle: 'Veuillez enregistrer les changements effectués.', actionButton: 'Enregistrer', - timeSheetStatus_verified: 'Vérifié', - timeSheetStatus_unverified: 'Invérifié', - timeSheetStatus_partial: 'Partiel', - timeSheetStatus_complete: 'Complet', - timeSheetStatus_empty: 'Vide', - timeSheetStatus_blocked: 'Bloqué', + timeSheetStatusVerified: 'validé', + timeSheetStatusUnverified: 'à valider', + timeSheetStatusPartial: 'partiellement validé', + timeSheetStatusComplete: 'complet', + timeSheetStatusEmpty: 'vide', + timeSheetStatusBlocked: 'bloqué', showAllCheckbox: 'Afficher tous', accumulatedSicknessTotal: 'Accumulées de maladies', consumedSicknessTotal: 'Consommées de maladies', diff --git a/src/modules/auth/composables/use-auth-api.ts b/src/modules/auth/composables/use-auth-api.ts index 6f14402..8a7b8c2 100644 --- a/src/modules/auth/composables/use-auth-api.ts +++ b/src/modules/auth/composables/use-auth-api.ts @@ -1,5 +1,5 @@ import { useAuthStore } from "../../../stores/auth-store"; -import type { User } from "src/modules/users/types/user-interface"; +import type { User } from "src/modules/shared/types/user-interface"; export const useAuthApi = () => { const authStore = useAuthStore(); diff --git a/src/modules/auth/pages/auth-login.vue b/src/modules/auth/pages/auth-login.vue index 012d43d..d08ca9d 100644 --- a/src/modules/auth/pages/auth-login.vue +++ b/src/modules/auth/pages/auth-login.vue @@ -1,8 +1,8 @@ + + \ No newline at end of file diff --git a/src/modules/shared/components/navigation/header-bar-avatar.vue b/src/modules/shared/components/navigation/header-bar-avatar.vue new file mode 100644 index 0000000..fea344d --- /dev/null +++ b/src/modules/shared/components/navigation/header-bar-avatar.vue @@ -0,0 +1,28 @@ + + + \ No newline at end of file diff --git a/src/modules/shared/components/navigation/header-bar.vue b/src/modules/shared/components/navigation/header-bar.vue new file mode 100644 index 0000000..253fd61 --- /dev/null +++ b/src/modules/shared/components/navigation/header-bar.vue @@ -0,0 +1,22 @@ + + + + diff --git a/src/modules/shared/components/navigation/right-drawer.vue b/src/modules/shared/components/navigation/right-drawer.vue new file mode 100644 index 0000000..9a65f45 --- /dev/null +++ b/src/modules/shared/components/navigation/right-drawer.vue @@ -0,0 +1,98 @@ + + + \ No newline at end of file diff --git a/src/modules/shared/types/pay-period-interface.ts b/src/modules/shared/types/pay-period-interface.ts new file mode 100644 index 0000000..7f9e3a3 --- /dev/null +++ b/src/modules/shared/types/pay-period-interface.ts @@ -0,0 +1,7 @@ +export interface PayPeriod { + period_number: number; + start_date: string; + end_date: string; + year: number; + label: string; +}; \ No newline at end of file diff --git a/src/modules/shared/types/user-interface.ts b/src/modules/shared/types/user-interface.ts new file mode 100644 index 0000000..f83f3af --- /dev/null +++ b/src/modules/shared/types/user-interface.ts @@ -0,0 +1,6 @@ +export interface User { + firstName: string; + lastName: string; + email: string; + role: string; +} \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue new file mode 100644 index 0000000..b63112c --- /dev/null +++ b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue @@ -0,0 +1,94 @@ + + + + \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/timesheet-approval-period-picker.vue b/src/modules/timesheet-approval/components/timesheet-approval-period-picker.vue new file mode 100644 index 0000000..a8f680e --- /dev/null +++ b/src/modules/timesheet-approval/components/timesheet-approval-period-picker.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/src/modules/timesheet-approval/pages/timesheet-approval.vue b/src/modules/timesheet-approval/pages/timesheet-approval.vue new file mode 100644 index 0000000..ed00b1d --- /dev/null +++ b/src/modules/timesheet-approval/pages/timesheet-approval.vue @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/modules/timesheet-approval/services/services-timesheet-approval.ts b/src/modules/timesheet-approval/services/services-timesheet-approval.ts new file mode 100644 index 0000000..6303eee --- /dev/null +++ b/src/modules/timesheet-approval/services/services-timesheet-approval.ts @@ -0,0 +1,37 @@ +import { api } from "src/boot/axios"; +import { mock_pay_periods } from "../timesheet-approval-test-constants"; +import type { PayPeriod } from "src/modules/shared/types/pay-period-interface"; + +export const timesheetApprovalService = { + getCurrentPayPeriod: (): PayPeriod => { + // TODO: REMOVE MOCK DATA PEFORE PUSHING TO PROD + //let current_pay_period: PayPeriod; + // + // try { + // console.log("Trying to get current pay period"); + // current_pay_period = await api.get(`/pay-periods/date/${(new Date()).toDateString()}`); + // return current_pay_period; + // } catch (err){ + // console.log(err); + // } + // console.log("failed to retrieve current pay period"); + + return { + "period_number": 15, + "start_date": "2025-07-27", + "end_date": "2025-08-09", + "year": 2025, + "label": "2025-07-27 → 2025-08-09" + } as PayPeriod; + }, + + getAllPayPeriods: async () => { + // TODO: REMOVE MOCK DATA PEFORE PUSHING TO PROD + return await api.get(`/pay-periods/`) || mock_pay_periods; + }, + + getPayPeriodEmployeeOverviews: async (period_number: number) => { + // TODO: REMOVE MOCK DATA PEFORE PUSHING TO PROD + return await api.get(`/pay-periods/${period_number}/overview`); + }, +}; \ No newline at end of file diff --git a/src/modules/timesheet-approval/timesheet-approval-test-constants.ts b/src/modules/timesheet-approval/timesheet-approval-test-constants.ts new file mode 100644 index 0000000..556bf7c --- /dev/null +++ b/src/modules/timesheet-approval/timesheet-approval-test-constants.ts @@ -0,0 +1,287 @@ +import type { PayPeriod } from "../shared/types/pay-period-interface"; +import type { PayPeriodEmployeeOverview } from "./types/timesheet-approval-pay-period-employee-overview-interface" + +export const mock_pay_period_employee_overviews: PayPeriodEmployeeOverview[] = [ + { + "employee_id": 'EMP-001', + "employee_name": 'Alice Johnson', + "regular_hours": 75, + "evening_hours": 12, + "emergency_hours": 3, + "overtime_hours": 5, + "expenses": 120.50, + "mileage": 45, + "is_approved": false + }, + { + "employee_id": 'EMP-002', + "employee_name": 'Brian Smith', + "regular_hours": 80, + "evening_hours": 8, + "emergency_hours": 0, + "overtime_hours": 2, + "expenses": 75.00, + "mileage": 12, + "is_approved": true + }, + { + "employee_id": 'EMP-003', + "employee_name": 'Chloe Ramirez', + "regular_hours": 68, + "evening_hours": 15, + "emergency_hours": 1, + "overtime_hours": 0, + "expenses": 200.00, + "mileage": 88, + "is_approved": false + }, + { + "employee_id": 'EMP-004', + "employee_name": 'David Lee', + "regular_hours": 82, + "evening_hours": 5, + "emergency_hours": 4, + "overtime_hours": 6, + "expenses": 50.75, + "mileage": 20, + "is_approved": true + }, + { + "employee_id": 'EMP-005', + "employee_name": 'Emily Carter', + "regular_hours": 78, + "evening_hours": 10, + "emergency_hours": 2, + "overtime_hours": 3, + "expenses": 95.25, + "mileage": 60, + "is_approved": false + }, + { + "employee_id": 'EMP-006', + "employee_name": 'Maxime Murray Gendron', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-007', + "employee_name": 'Marc-André Henrico', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-008', + "employee_name": 'Jessy Sharock', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-009', + "employee_name": 'David Richer', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-010', + "employee_name": 'Nicolas Drolet', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-011', + "employee_name": 'Frederick Pruneau', + "regular_hours": 16, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-012', + "employee_name": 'Matthieu Haineault Gervais', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-013', + "employee_name": 'Robinson Viaud', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-014', + "employee_name": 'Geneviève Bourdon', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-015', + "employee_name": 'Frédérique Soulard', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-016', + "employee_name": 'Patrick Doucet', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-017', + "employee_name": 'Dahlia Tremblay', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-018', + "employee_name": 'Louis Morneau', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-019', + "employee_name": 'Michel Blais', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + } +]; + +export const mock_pay_periods: PayPeriod[] = [ + { + "period_number": 15, + "start_date": "2025-07-27", + "end_date": "2025-08-09", + "year": 2025, + "label": "2025-07-27 → 2025-08-09" + }, + { + "period_number": 14, + "start_date": "2025-07-13", + "end_date": "2025-07-26", + "year": 2025, + "label": "2025-07-13 → 2025-07-26" + }, + { + "period_number": 13, + "start_date": "2025-06-29", + "end_date": "2025-07-12", + "year": 2025, + "label": "2025-06-29 → 2025-07-12" + }, + { + "period_number": 12, + "start_date": "2025-06-15", + "end_date": "2025-06-28", + "year": 2025, + "label": "2025-06-15 → 2025-06-28" + }, + { + "period_number": 11, + "start_date": "2025-06-01", + "end_date": "2025-06-14", + "year": 2025, + "label": "2025-06-01 → 2025-06-14" + }, + { + "period_number": 10, + "start_date": "2025-05-18", + "end_date": "2025-05-31", + "year": 2025, + "label": "2025-05-18 → 2025-05-31" + }, + { + "period_number": 9, + "start_date": "2025-05-04", + "end_date": "2025-05-17", + "year": 2025, + "label": "2025-05-04 → 2025-05-17" + }, + { + "period_number": 8, + "start_date": "2025-04-20", + "end_date": "2025-05-03", + "year": 2025, + "label": "2025-04-20 → 2025-05-03" + }, + { + "period_number": 7, + "start_date": "2025-04-06", + "end_date": "2025-04-19", + "year": 2025, + "label": "2025-04-06 → 2025-04-19" + }, + { + "period_number": 6, + "start_date": "2025-03-23", + "end_date": "2025-04-05", + "year": 2025, + "label": "2025-03-23 → 2025-04-05" + } +] diff --git a/src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-overview-interface.ts b/src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-overview-interface.ts new file mode 100644 index 0000000..f935687 --- /dev/null +++ b/src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-overview-interface.ts @@ -0,0 +1,11 @@ +export interface PayPeriodEmployeeOverview { + employee_id: string; + employee_name: string; + regular_hours: number; + evening_hours: number; + emergency_hours: number; + overtime_hours: number; + expenses: number; + mileage: number; + is_approved: boolean; +}; \ No newline at end of file diff --git a/src/modules/timesheet-approval/types/timesheet-approval-pay-period-overview-interface.ts b/src/modules/timesheet-approval/types/timesheet-approval-pay-period-overview-interface.ts new file mode 100644 index 0000000..130ee40 --- /dev/null +++ b/src/modules/timesheet-approval/types/timesheet-approval-pay-period-overview-interface.ts @@ -0,0 +1,6 @@ +export interface PayPeriodOverview { + period_number: number; + start_date: string; + end_date: string; + label: string; +}; \ No newline at end of file diff --git a/src/pages/error-page.vue b/src/pages/error-page.vue index bc41d10..cbe39b9 100644 --- a/src/pages/error-page.vue +++ b/src/pages/error-page.vue @@ -3,25 +3,21 @@ \ No newline at end of file diff --git a/src/router/router-constants.ts b/src/router/router-constants.ts new file mode 100644 index 0000000..b264bf2 --- /dev/null +++ b/src/router/router-constants.ts @@ -0,0 +1,9 @@ +export enum RouteNames { + /* eslint-disable */ + LOGIN = 'login', + LOGIN_SUCCESS = 'login-success', + DASHBOARD = 'dashboard', + TIMESHEET_APPROVALS = 'timesheet-approvals', + EMPLOYEE_LIST = 'employee-list', + PROFILE = 'user/profile', +} \ No newline at end of file diff --git a/src/router/routes.ts b/src/router/routes.ts index 0c13dc2..18509ef 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -1,4 +1,5 @@ import type { RouteRecordRaw } from 'vue-router'; +import { RouteNames } from './router-constants'; const routes: RouteRecordRaw[] = [ { @@ -8,22 +9,27 @@ const routes: RouteRecordRaw[] = [ children: [ { path: '', - name: 'dashboard', + name: RouteNames.DASHBOARD, component: () => import('src/pages/test-page.vue'), }, + { + path: 'timesheet-approvals', + name: RouteNames.TIMESHEET_APPROVALS, + component: () => import('src/modules/timesheet-approval/pages/timesheet-approval.vue'), + }, ], }, { path: '/v1/login', - name: 'login', + name: RouteNames.LOGIN, component: () => import('src/modules/auth/pages/auth-login.vue'), meta: { requiresAuth: false }, }, { path: '/login-success', - name: 'login-success', + name: RouteNames.LOGIN_SUCCESS, component: () => import('src/modules/auth/pages/auth-login-popup-success.vue'), meta: { requiresAuth: false }, }, diff --git a/src/stores/auth-store.ts b/src/stores/auth-store.ts new file mode 100644 index 0000000..19a601e --- /dev/null +++ b/src/stores/auth-store.ts @@ -0,0 +1,39 @@ +import { computed, ref } from "vue"; +import { defineStore } from "pinia"; +import { AuthService } from "../modules/auth/services/services-auth"; +import type { User } from "src/modules/shared/types/user-interface"; + +const defaultUser: User = { + firstName: 'Unknown', + lastName: 'Unknown', + email: 'guest@guest.com', + role: 'guest' + }; + +export const useAuthStore = defineStore('auth', () => { + const user = ref (defaultUser); + const authError = ref(""); + const isAuthorizedUser = computed(() => user.value.role !== 'guest'); + + const login = () => { + //TODO: manage customer login process + }; + + const oidcLogin = () => { + const oidcPopup = AuthService.oidcLogin(); + if (!oidcPopup) { + authError.value = "You have popups blocked on this website!"; + } + }; + + const logout = () => { + user.value = defaultUser; + }; + + const setUser = (currentUser: User) => { + user.value = currentUser; + }; + + return { user, authError, isAuthorizedUser, login, oidcLogin, logout, setUser }; +}); + diff --git a/src/stores/timesheet-store.ts b/src/stores/timesheet-store.ts new file mode 100644 index 0000000..a6b79d3 --- /dev/null +++ b/src/stores/timesheet-store.ts @@ -0,0 +1,232 @@ +import { defineStore } from 'pinia'; +import { ref } from 'vue'; +import { timesheetApprovalService } from 'src/modules/timesheet-approval/services/services-timesheet-approval'; +import type { PayPeriod } from 'src/modules/shared/types/pay-period-interface'; +import type { PayPeriodEmployeeOverview } from "src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-overview-interface"; + + +const default_current_pay_period: PayPeriod = {"period_number": 1, "start_date": "1970-01-01", "end_date": "1970-01-15", "year": 1970, "label": "1970-01-01 → 1970-01-15"}; + +const mock_pay_period_employee_overviews: PayPeriodEmployeeOverview[] = [ + { + "employee_id": 'EMP-001', + "employee_name": 'Alice Johnson', + "regular_hours": 75, + "evening_hours": 12, + "emergency_hours": 3, + "overtime_hours": 5, + "expenses": 120.50, + "mileage": 45, + "is_approved": false + }, + { + "employee_id": 'EMP-002', + "employee_name": 'Brian Smith', + "regular_hours": 80, + "evening_hours": 8, + "emergency_hours": 0, + "overtime_hours": 2, + "expenses": 75.00, + "mileage": 12, + "is_approved": true + }, + { + "employee_id": 'EMP-003', + "employee_name": 'Chloe Ramirez', + "regular_hours": 68, + "evening_hours": 15, + "emergency_hours": 1, + "overtime_hours": 0, + "expenses": 200.00, + "mileage": 88, + "is_approved": false + }, + { + "employee_id": 'EMP-004', + "employee_name": 'David Lee', + "regular_hours": 82, + "evening_hours": 5, + "emergency_hours": 4, + "overtime_hours": 6, + "expenses": 50.75, + "mileage": 20, + "is_approved": true + }, + { + "employee_id": 'EMP-005', + "employee_name": 'Emily Carter', + "regular_hours": 78, + "evening_hours": 10, + "emergency_hours": 2, + "overtime_hours": 3, + "expenses": 95.25, + "mileage": 60, + "is_approved": false + }, + { + "employee_id": 'EMP-006', + "employee_name": 'Maxime Murray Gendron', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 20000, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-007', + "employee_name": 'Marc-André Henrico', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-008', + "employee_name": 'Jessy Sharock', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-009', + "employee_name": 'David Richer', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-010', + "employee_name": 'Nicolas Drolet', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-011', + "employee_name": 'Frederick Pruneau', + "regular_hours": 16, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-012', + "employee_name": 'Matthieu Haineault Gervais', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-013', + "employee_name": 'Robinson Viaud', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-014', + "employee_name": 'Geneviève Bourdon', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-015', + "employee_name": 'Frédérique Soulard', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-016', + "employee_name": 'Patrick Doucet', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-017', + "employee_name": 'Dahlia Tremblay', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-018', + "employee_name": 'Louis Morneau', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + }, + { + "employee_id": 'EMP-019', + "employee_name": 'Michel Blais', + "regular_hours": 80, + "evening_hours": 0, + "emergency_hours": 0, + "overtime_hours": 0, + "expenses": 0, + "mileage": 0, + "is_approved": false + } +]; + +export const useTimesheetStore = defineStore('timesheet', () => { + const payPeriods = ref([]); + const currentPayPeriod = ref(default_current_pay_period); + const payPeriodEmployeeOverviews = ref(mock_pay_period_employee_overviews); + + const getCurrentPayPeriod = () => { + currentPayPeriod.value = timesheetApprovalService.getCurrentPayPeriod(); + } + + return { payPeriods, currentPayPeriod, payPeriodEmployeeOverviews, getCurrentPayPeriod}; +}); diff --git a/src/stores/ui-store.ts b/src/stores/ui-store.ts new file mode 100644 index 0000000..5743f8f --- /dev/null +++ b/src/stores/ui-store.ts @@ -0,0 +1,11 @@ +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const useUiStore = defineStore('ui', () => { + const isRightDrawerOpen = ref(true); + const toggleRightDrawer = () => { + isRightDrawerOpen.value = !isRightDrawerOpen.value; + } + + return { isRightDrawerOpen, toggleRightDrawer }; +}); diff --git a/src/utils/has-required-role.ts b/src/utils/has-required-role.ts new file mode 100644 index 0000000..dbd7056 --- /dev/null +++ b/src/utils/has-required-role.ts @@ -0,0 +1,7 @@ +import { useAuthStore } from "src/stores/auth-store"; + +export const hasRequiredRole = (...requiredRoles: string[] ) => { + const currentUserRole = useAuthStore().user.role; + + return requiredRoles.includes(currentUserRole); +}; \ No newline at end of file