diff --git a/public/favicon.ico b/public/favicon.ico index ae7bbdb..d138bc0 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/icons/favicon-128x128.png b/public/icons/favicon-128x128.png index 1401176..bfae8af 100644 Binary files a/public/icons/favicon-128x128.png and b/public/icons/favicon-128x128.png differ diff --git a/public/icons/favicon-16x16.png b/public/icons/favicon-16x16.png index 679063a..ee862c9 100644 Binary files a/public/icons/favicon-16x16.png and b/public/icons/favicon-16x16.png differ diff --git a/public/icons/favicon-32x32.png b/public/icons/favicon-32x32.png index fd1fbc6..da2adff 100644 Binary files a/public/icons/favicon-32x32.png and b/public/icons/favicon-32x32.png differ diff --git a/public/icons/favicon-96x96.png b/public/icons/favicon-96x96.png index e93b80a..34afaba 100644 Binary files a/public/icons/favicon-96x96.png and b/public/icons/favicon-96x96.png differ diff --git a/quasar.config.ts b/quasar.config.ts index 85e63ab..34af8ea 100644 --- a/quasar.config.ts +++ b/quasar.config.ts @@ -101,7 +101,12 @@ export default defineConfig((ctx) => { // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#framework framework: { - config: {}, + config: { + notify: { + color: 'primary', + avatar: 'https://cdn.quasar.dev/img/boy-avatar.png', + } + }, // iconSet: 'material-icons', // Quasar icon set // lang: 'en-US', // Quasar language pack @@ -114,7 +119,9 @@ export default defineConfig((ctx) => { // directives: [], // Quasar plugins - plugins: [] + plugins: [ + 'Notify' + ] }, // animations: 'all', // --- includes all animations diff --git a/src/assets/fond-1-maisons.png b/src/assets/fond-1-maisons.png new file mode 100644 index 0000000..597bad3 Binary files /dev/null and b/src/assets/fond-1-maisons.png differ diff --git a/src/assets/line-truck-1.jpg b/src/assets/line-truck-1.jpg new file mode 100644 index 0000000..54b601c Binary files /dev/null and b/src/assets/line-truck-1.jpg differ diff --git a/src/assets/logo-targo-green.png b/src/assets/logo-targo-green.png new file mode 100644 index 0000000..00c4567 Binary files /dev/null and b/src/assets/logo-targo-green.png differ diff --git a/src/assets/logo-targo-simple-white.svg b/src/assets/logo-targo-simple-white.svg new file mode 100644 index 0000000..33d8a36 --- /dev/null +++ b/src/assets/logo-targo-simple-white.svg @@ -0,0 +1,19 @@ + + + +Created with Fabric.js 5.2.4 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/logo-targo-simple.svg b/src/assets/logo-targo-simple.svg new file mode 100644 index 0000000..eec6bd6 --- /dev/null +++ b/src/assets/logo-targo-simple.svg @@ -0,0 +1,22 @@ + + + +Created with Fabric.js 5.2.4 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/logo-targo-white.png b/src/assets/logo-targo-white.png new file mode 100644 index 0000000..8451291 Binary files /dev/null and b/src/assets/logo-targo-white.png differ diff --git a/src/assets/logo-targo-white.svg b/src/assets/logo-targo-white.svg new file mode 100644 index 0000000..6f748fe --- /dev/null +++ b/src/assets/logo-targo-white.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logo-targo.svg b/src/assets/logo-targo.svg new file mode 100644 index 0000000..6860896 --- /dev/null +++ b/src/assets/logo-targo.svg @@ -0,0 +1,28 @@ + + + +Created with Fabric.js 5.2.4 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/boot/i18n.ts b/src/boot/i18n.ts index c351b01..1ff7956 100644 --- a/src/boot/i18n.ts +++ b/src/boot/i18n.ts @@ -1,7 +1,7 @@ import { defineBoot } from '#q-app/wrappers'; import { createI18n } from 'vue-i18n'; -import messages from 'src/modules/i18n'; +import messages from 'src/i18n'; export type MessageLanguages = keyof typeof messages; // Type-define 'en-US' as the master schema for the resource @@ -23,7 +23,7 @@ declare module 'vue-i18n' { export default defineBoot(({ app }) => { const i18n = createI18n<{ message: MessageSchema }, MessageLanguages>({ - locale: 'en-ca', + locale: 'fr-ca', legacy: false, messages, }); diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 3996ce1..70584c1 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -12,14 +12,17 @@ // to match your app's branding. // Tip: Use the "Theme Builder" on Quasar's documentation website. -$primary : #1976D2; -$secondary : #26A69A; -$accent : #9C27B0; +$primary: #019547; +$secondary: #dadded; +$accent: #1976d2; -$dark : #1D1D1D; -$dark-page : #121212; +$dark-font: #305530; -$positive : #21BA45; -$negative : #C10015; -$info : #31CCEC; -$warning : #F2C037; +$dark: #111212; +$dark-page: #121212; + +$positive: #21ba45; +$negative: #c10015; +$info: #31ccec; +$warning: #eeb10a; +$white: white; diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index d555d3f..60dcb6e 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -1,7 +1,392 @@ -// This is just an example, -// so you can safely delete all default props below - export default { - failed: 'Action failed', - success: 'Action was successful' + mainLayout: { + backButton: 'Back to home', + clearFilter: 'Clear filter', + }, + helpPage: { + title_1: 'Contact Us', + title_2: + 'Please complete the form below and we’ll get back to you as soon as possible.', + fullName: 'Full name*', + email: 'Email address*', + phoneNumber: 'Phone number*', + message: + 'How can we help you? Please use this area to provide a detailed message, Thank you!*', + //form validation + fullNameValidation: 'Full name must be filled in.', + emailValidation: 'Email must be a valid email.', + phoneNumberValidation: 'Phone number must be filled in.', + messageValidation: 'Message must be a valid email.', + submit: 'Send', + }, + navBar: { + navItem_1: 'Users list', + navItem_2: 'Shift validations', + menuItem_1: 'Profile', + menuItem_2: 'Help', + menuItem_3: 'Log Out', + menuItem_4: 'Time Sheet', + menuItem_5: 'Annual calendar', + mobileIndexTitle: 'Hi', + }, + notFoundPage: { + pageTitle: 'Oops. Nothing here...', + backButton: 'Go to the home page', + }, + footerLayout: { + title: `Targo Communications, 2005 - 2025)}. All rights reserved.`, + }, + loginPage: { + title: 'Log in to Targo', + forgotPassword: 'Forgot Password?', + signUp: 'Don’t have an account yet?', + email: 'Email', + password: 'Password', + submit: 'Sign in ', + authentik: 'Targo authentication', + emailValidation: 'Email must be a valid email.', + passwordValidation: 'Password must be a valid email.', + }, + signUpPage: { + title: 'Create a new account', + firstName: 'First name', + lastName: 'Last name', + email: 'Email', + phoneNumber: 'Phone number', + password: 'New password', + confirmedPassword: 'Confirm your password', + signIn: 'Already have an account?', + submit: 'Sign up', + firstNameValidation: 'First Name must be filled in.', + lastNameValidation: 'Last Name must be filled in.', + emailValidation: 'Email must be a valid email.', + phoneNumberValidation: 'Phone number must be filled in.', + passwordValidationTitle: 'Password Criteria :', + passwordValidation: 'Password must meet all criteria.', + passwordLengthValidation: 'Must be at least 8 characters long.', + passwordCapitalValidation: 'Must contain at least one capital letter.', + passwordNumberValidation: 'Must contain at least one number.', + passwordSpecialCharacterValidation: + 'Must contain at least one special character: !@#$%^&*()-_+=', + confirmPasswordValidation: 'Password must match new Password.', + }, + forgotPage: { + title: + 'Please enter your email to search for your account and send a verification code.', + email: 'Email', + emailValidation: 'Email must be a valid email.', + submit: 'Send Code', + cancel: 'Cancel', + }, + resetPage: { + title: 'Reset your password', + code: 'code', + codeValidation: 'Code must be filled in with 4 digits.', + newPassword: 'New Password', + confirmedPassword: 'Confirm New Password', + newPasswordValidation: 'Password must meet all criteria.', + newPasswordLengthValidation: 'Must be at least 8 characters long.', + newPasswordCapitalValidation: 'Must contain at least one capital letter.', + newPasswordNumberValidation: 'Must contain at least one number.', + newPasswordSpecialCharacterValidation: + 'Must contain at least one special character: !@#$%^&*()-_+=', + confirmNewPasswordValidation: 'Password must match new Password.', + submit: 'Send', + cancel: 'Cancel', + }, + accountDialog: { + title: 'More', + item_1: 'Language', + item_2: 'Profil', + item_3: 'Log Out', + item_4: 'Time Sheet', + item_5: 'Annual calendar', + }, + notificationDialog: { + notice: 'Notice', + markAllRead: 'Mark all read', + deleteAll: 'Delete all', + close: 'Close', + }, + profilePage: { + title: 'Profile', + firstName: 'First name', + lastName: 'Last name', + email: 'Email', + phoneNumber: 'Phone number', + job_title: 'Job title', + company: 'Company', + supervisor: 'Supervisor', + role: 'Role', + address: 'Address', + job_titleValidation: 'Job title must be filled in.', + companyValidation: 'Company must be filled in.', + supervisorValidation: 'Supervisor must be filled in.', + roleValidation: 'Role must be filled in.', + addressValidation: 'Address must be filled in.', + firstNameValidation: 'First Name must be filled in.', + lastNameValidation: 'Last Name must be filled in.', + phoneNumberValidation: 'Phone number must be filled in.', + submit: 'Update Profile', + }, + indexAdminPage: { + card_1: 'Administrators', + card_2: 'Technicians', + card_3: 'Dealer', + card_4: 'Customers', + }, + usersListPage: { + tableHeader: 'Users list', + search_input: 'Search', + tableCol_1: 'Status', + tableCol_2: 'First name', + tableCol_3: 'Last name', + tableCol_4: 'Email', + tableCol_5: 'Phone number', + tableCol_6: 'User type', + tableCol_7: 'Role', + tableCol_8: 'Created by', + tableCol_9: 'Supervisor', + activeStatus: 'Active', + unActiveStatus: 'Unactive', + addButton: 'Click here to add a new user', + customer: 'Customer', + dealer: 'Dealer', + employee: 'Employee', + technician: 'Technician', + admin: 'Administrator', + support: 'Support', + }, + editUserPage: { + title: 'Edit Account', + passwordTitle: 'Reset Password', + firstName: 'First name', + lastName: 'Last name', + email: 'Email', + phoneNumber: 'Phone number', + type: 'Select a type', + role: 'Select a role', + job_title: 'Job title', + company: 'Company', + supervisor: 'Supervisor', + isSupervisor: 'Is supervisor', + hours_bank_max: 'Hours bank maximum', + address: 'Address', + verifiedAccountStatus: 'Verified Account', + unVerifiedAccountStatus: 'UnVerified Account', + password: 'New password', + confirmedPassword: 'Confirm your password', + submit: 'Update Account', + //Form Validation + firstNameValidation: 'First Name must be filled in.', + lastNameValidation: 'Last Name must be filled in.', + emailValidation: 'Email must be a valid email.', + phoneNumberValidation: 'Phone number must be filled in.', + typeValidation: 'Type must be filled in.', + roleValidation: 'Role must be filled in.', + job_titleValidation: 'Job title must be filled in.', + companyValidation: 'Company must be filled in.', + supervisorValidation: 'Supervisor must be filled in.', + hours_bank_maxValidation: 'Hours bank maximum must be filled in.', + addressValidation: 'Address must be filled in.', + passwordValidation: 'Password must meet all criteria.', + confirmPasswordValidation: 'Password must match new Password.', + }, + addUserPage: { + title: 'Create User', + firstName: 'First name', + lastName: 'Last name', + email: 'Email', + phoneNumber: 'Phone number', + type: 'Select a type', + role: 'Select a role', + job_title: 'Job title', + company: 'Company', + supervisor: 'Supervisor', + isSupervisor: 'Is supervisor', + hours_bank_max: 'Hours bank maximum', + onboarding: 'Onboarding date', + offboarding: 'Offboarding date', + employee_number: 'Employee number (Employer D number)', + regular_hours_day: 'regular number of hours per day', + address: 'Address', + verifiedAccountStatus: 'Verified Account', + unVerifiedAccountStatus: 'UnVerified Account', + password: 'Password', + confirmedPassword: 'Confirm your password', + submit: 'Create', + //Form Validaiton + firstNameValidation: 'First Name must be filled in.', + lastNameValidation: 'Last Name must be filled in.', + emailValidation: 'Email must be a valid email.', + phoneNumberValidation: 'Phone number must be filled in.', + typeValidation: 'Type must be filled in.', + roleValidation: 'Role must be filled in.', + job_titleValidation: 'Job title must be filled in.', + companyValidation: 'Company must be filled in.', + supervisorValidation: 'Supervisor must be filled in.', + hours_bank_maxValidation: 'Hours bank maximum must be filled in.', + onboardingValidation: 'Onboarding date must be filled in.', + employee_numberValidation: 'Employee number must be filled in.', + regular_hours_dayValidation: + 'regular number of hours per day must be filled in.', + addressValidation: 'Address must be filled in.', + passwordValidation: 'Password must meet all criteria.', + confirmPasswordValidation: 'Password must match new Password.', + }, + pagesTitles: { + newUserPageTitle: 'New user', + updateUserPageTitle: 'Update user', + timeSheetPageTitle: 'Time sheet', + timeSheetValidationsIdPageTitle: 'Time sheet', + }, + timeSheet: { + timeSheetTab_1: 'Shifts', + timeSheetTab_2: 'Expenses', + templateButton: 'Apply Templates', + shiftTemplateTitle: 'Set up your day schedule', + shiftType: 'Type', + remoteShift: 'Remote', + shiftStartTime: 'Start time', + shiftEndTime: 'End time', + shiftComment: 'Comment', + overTimeTitle: 'Overtime regular hours: ', + totalPayedHours: 'Total hours worked: ', + //shiftOptions + regularShift: 'Regular', + eveningShift: 'Evening', + emergencyShift: 'Emergency', + sickDay: 'Sick working day', + vacancyDay: 'vacation', + holiday: 'Holiday', + dateRangesWeek: 'Week from', + dateRangesTo: 'to', + shiftBankedHours: 'Total hours to bank', + bankedHoursHint_1: ' on', + bankedHoursHint_2: ' accumulated hours', + qTimeClose: 'Close', + saveButton: 'Save', + //shift validations + timeSheetValidated: 'Validated week', + timeSheetBlocked: 'Blocked week', + shiftTypeValidation: 'Type must be filled in.', + shiftStartTimeValidation: 'Start time must be filled in.', + shiftEndTimeValidation: 'End time must be filled in.', + endTimeValidation: 'The end time cannot be before or equal the start time', + expensesTile: 'daily expenses', + expensesType: 'Type', + expensesValue: 'amount', + expensesDescription: 'Description', + expensesEvidence: 'attachment', + //expenses validations + expensesTypeValidation: 'Type must be filled in.', + expensesValueValidation: 'Amount must be filled in.', + //expensesOptions + refund: 'Refund', + garde: 'Garde', + perdiem: 'Perdiem', + mileage: 'Mileage', + }, + 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', + 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', + showAllCheckbox: 'Show all', + accumulatedSicknessTotal: 'Accumulated illnesses', + consumedSicknessTotal: 'Consumed with illnesses', + accumulatedVacationTotal: 'Accumulated vacation', + consumedVacationTotal: 'Consumed with vacation', + maxVacationPerYear: 'Maximum vacation per year', + accumulatedSicknessTotalValidation: + 'Accumulated illnesses must be positive.', + consumedSicknessTotalValidation: + 'Consumed with illnesses must be positive.', + accumulatedVacationTotalValidation: + 'Accumulated vacation must be positive.', + consumedVacationTotalValidation: 'Consumed with vacation must be positive.', + maxVacationPerYearValidation: 'Max Vacation Per Year must be positive.', + resteVacationTotal: 'Rest of vacation', + validateToolTip: 'Validate', + unvalidateToolTip: 'Unvalidate', + lockToolTip: 'Lock the week', + unlockToolTip: 'Unlock the week', + }, + shiftColumns: { + title: 'Shifts', + column_1: 'Type', + column_2: 'Start time', + column_3: 'End time', + column_4: 'Comment', + column_5: 'Status', + column_6: 'Supervisor’s report', + }, + expenseColumns: { + title: 'Expenses', + column_1: 'Type', + column_2: 'Amount', + column_3: 'Attachment', + column_4: 'Description', + column_5: 'Status', + column_6: 'Supervisor’s report', + }, + table: { + recordsTitle: 'Records per page:', + noResultsLabel: 'The filter didn’t uncover any results', + noDataLabel: 'I didn’t find anything for you', + }, + autoLogout: { + title: 'Alert', + message_start: 'Attention: You will be automatically logged out in', + message_end: 'seconds if you do not interact with the screen.', + }, + daysOfWeek: { + Sunday: ' Sunday', + Monday: 'Monday', + Tuesday: 'Tuesday', + Wednesday: 'Wednesday', + Thursday: 'Thursday', + Friday: 'Friday', + Saturday: 'Saturday', + }, + shiftsTemplate: { + tabTitle1: 'Shifts', + tabTitle2: 'Templates for shifts', + saveButton: 'Save', + emptyShiftsMessage: 'No shifts available.', + emptyTemplateMessage: 'No template available.', + selectTemplate: 'Select a template', + selectTemplateNoResult: 'No template available.', + selectDay: 'Day', + startTime: 'Start time', + endTime: 'End time', + templateTitle: 'Title', + templateDescription: 'Description', + createButton: 'Create', + updateButton: 'Update', + deleteButton: 'Delete', + resetButton: 'Reset', + dayValidation: 'Day must be filled in.', + startTimeValidation: 'Start time must be filled in.', + endTimeValidation: 'End time must be filled in.', + startTimeAfterEndTimeValidation: + 'The end time cannot be before or equal the start time', + endTimeBeforeStartTimeValidation: + 'The end time cannot be before or equal the start time', + existingTimeShift: 'This time is already in use', + }, }; diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts new file mode 100644 index 0000000..0c13762 --- /dev/null +++ b/src/i18n/fr-ca/index.ts @@ -0,0 +1,401 @@ +export default { + mainLayout: { + backButton: 'Retour à la page d’accueil', + clearFilter: 'Effacer le filtre', + }, + helpPage: { + title_1: 'Contactez-nous', + title_2: + 'Veuillez remplir le formulaire ci-dessous et nous vous communiquerons dès que possible.', + fullName: 'Nom complet*', + email: 'Adresse e-mail*', + phoneNumber: 'Numéro de téléphone*', + message: + 'Comment pouvons-nous vous aider? S’il vous plaît utiliser cette zone pour fournir un message détaillé, Merci!*', + //form validation + fullNameValidation: 'Le nom complet doit être rempli.', + emailValidation: 'L’e-mail doit être un e-mail valide.', + phoneNumberValidation: 'Le numéro de téléphone doit être rempli.', + messageValidation: 'Message doit être rempli.', + submit: 'Envoyer', + }, + navBar: { + navItem_1: 'Liste des utilisateurs', + navItem_2: 'Validations des quarts de travail', + menuItem_1: 'Profil', + menuItem_2: 'Aide', + menuItem_3: 'Déconnexion', + menuItem_4: 'Carte de temps', + menuItem_5: 'Calendrier annuel', + mobileIndexTitle: 'Bonjour', + }, + notFoundPage: { + pageTitle: 'Oops. Rien ici...', + backButton: 'Aller à la page d’accueil', + }, + footerLayout: { + title: `Targo Canada, 2005 - 2025. Tous droits réservés.`, + }, + loginPage: { + title: 'Se connecter à Targo', + forgotPassword: 'Mot de passe oublié?', + signUp: 'Vous n’avez pas encore de compte?', + email: 'Email', + password: 'Mot de passe', + submit: 'Se connecter', + authentik: 'Authentification Targo', + emailValidation: 'Email doit être un e-mail valide.', + passwordValidation: 'Mot de passe doit être rempli.', + }, + signUpPage: { + title: 'Créer un nouveau compte', + firstName: 'Prénom', + lastName: 'Nom de famille', + email: 'Email', + phoneNumber: 'Numéro de téléphone', + password: 'Nouveau mot de passe', + confirmedPassword: 'Confirmez votre mot de passe', + signIn: 'Vous avez déjà un compte?', + submit: 'S’inscrire', + firstNameValidation: 'Le prénom doit être rempli.', + lastNameValidation: 'Le nom de famille doit être rempli.', + emailValidation: 'Email doit être un e-mail valide.', + phoneNumberValidation: 'Numéro de téléphone doit être rempli.', + passwordValidationTitle: 'Critères de mot de passe :', + passwordValidation: 'Le mot de passe doit répondre à tous les critères.', + passwordLengthValidation: 'Doit être d’au moins 8 caractères de long.', + passwordCapitalValidation: 'Doit contenir au moins une lettre majuscule.', + passwordNumberValidation: 'Doit contenir au moins un numéro.', + passwordSpecialCharacterValidation: + 'Doit contenir au moins un caractère spécial : !@#$%^&*()-_+=', + confirmPasswordValidation: + 'Le mot de passe doit correspondre au nouveau mot de passe.', + }, + forgotPage: { + title: + 'Veuillez saisir votre e-mail pour rechercher votre compte et envoyer un code de vérification.', + email: 'Email', + emailValidation: 'Email doit être un e-mail valide.', + submit: 'Envoyer code', + cancel: 'Annuler', + }, + resetPage: { + title: 'Réinitialiser votre mot de passe', + code: 'code', + codeValidation: 'Le code doit être rempli avec 4 chiffres.', + newPassword: 'Nouveau mot de passe', + confirmedPassword: 'Confirmez votre mot de passe', + newPasswordValidation: 'Le mot de passe doit répondre à tous les critères.', + newPasswordLengthValidation: 'Doit être d’au moins 8 caractères de long.', + newPasswordCapitalValidation: + 'Doit contenir au moins une lettre majuscule.', + newPasswordNumberValidation: 'Doit contenir au moins un numéro.', + newPasswordSpecialCharacterValidation: + 'Doit contenir au moins un caractère spécial : !@#$%^&*()-_+=', + confirmNewPasswordValidation: + 'Le mot de passe doit correspondre au nouveau mot de passe.', + submit: 'Envoyer', + cancel: 'Annuler', + }, + accountDialog: { + title: 'Plus', + item_1: 'Langue', + item_2: 'Profile', + item_3: 'Déconnexion', + item_4: 'Carte de temps', + item_5: 'Calendrier annuel', + }, + notificationDialog: { + notice: 'Notification', + markAllRead: 'Marquer tout comme lu', + deleteAll: 'Supprimer tout', + close: 'Fermer', + }, + profilePage: { + title: 'Profil', + firstName: 'Prénom', + lastName: 'Nom de famille', + email: 'Email', + phoneNumber: 'Numéro de téléphone', + job_title: 'Titre du poste', + company: 'Entreprise', + supervisor: 'Superviseur', + role: 'Role', + address: 'Adresse', + job_titleValidation: 'Le champ "titre du poste" doit être rempli.', + companyValidation: 'Le champ "entreprise" doit être rempli.', + supervisorValidation: 'Un employé qui n’a pas le rôle de superviseur doit être attribué à un superviseur.', + roleValidation: 'Le champ "rôle" doit être rempli.', + addressValidation: 'Le champ "adresse" doit être rempli.', + firstNameValidation: 'Le champ "prénom" doit être rempli.', + lastNameValidation: 'Le champ "nom de famille" doit être rempli.', + phoneNumberValidation: 'Le champ "numéro de téléphone" doit être rempli.', + submit: 'Modifier Profil', + }, + indexAdminPage: { + card_1: 'Administrateurs', + card_2: 'Techniciens', + card_3: 'Marchand', + card_4: 'Clients', + }, + usersListPage: { + tableHeader: 'Liste des utilisateurs', + search_input: 'Rechercher', + tableCol_1: 'État', + tableCol_2: 'Prénom', + tableCol_3: 'Nom de famille', + tableCol_4: 'Email', + tableCol_5: 'Numéro de téléphone', + tableCol_6: 'Type d’utilisateur', + tableCol_7: 'Role', + tableCol_8: 'Créé par', + tableCol_9: 'Superviseur', + activeStatus: 'Actif', + unActiveStatus: 'Inactif', + addButton: 'Cliquez ici pour ajouter un nouvel utilisateur', + customer: 'Client', + dealer: 'Marchand', + employee: 'Employé', + technician: 'Technicien', + admin: 'Administrateur', + support: 'Support', + }, + editUserPage: { + title: 'Modifier le compte', + passwordTitle: 'Réinitialiser le mot de passe', + firstName: 'Prénom', + lastName: 'Nom de famille', + email: 'Email', + phoneNumber: 'Numéro de téléphone', + type: 'Choisir un type', + role: 'Choisir un role', + job_title: 'Titre d’emploi', + company: 'Entreprise', + supervisor: 'Superviseur', + isSupervisor: 'Est un superviseur', + hours_bank_max: 'Maximum de banque d’heures ', + address: 'Adresse', + verifiedAccountStatus: 'Compte vérifié', + unVerifiedAccountStatus: 'Compte non vérifié', + password: 'Nouveau mot de passe', + confirmedPassword: 'Confirmez votre mot de passe', + submit: 'Modifier le compte', + //Form Validaiton + firstNameValidation: 'Le prénom doit être rempli.', + lastNameValidation: 'Le nom de famille doit être rempli.', + emailValidation: 'Email doit être un e-mail valide.', + phoneNumberValidation: 'Numéro de téléphone doit être rempli.', + typeValidation: 'Type doit être rempli.', + roleValidation: 'Role doit être rempli.', + job_titleValidation: 'Le Titre d’emploi doit être rempli.', + companyValidation: 'Entreprise doit être rempli.', + supervisorValidation: 'Superviseur doit être rempli.', + hours_bank_maxValidation: 'Maximum de banque d’heures doit être rempli.', + addressValidation: 'Adresse doit être rempli.', + passwordValidation: 'Le mot de passe doit répondre à tous les critères.', + confirmPasswordValidation: + 'Le mot de passe doit correspondre au nouveau mot de passe.', + }, + addUserPage: { + title: 'Créer un utilisateur', + firstName: 'Prénom', + lastName: 'Nom de famille', + email: 'Email', + phoneNumber: 'Numéro de téléphone', + type: 'Choisir un type', + role: 'Choisir un role', + job_title: 'Titre d’emploi', + company: 'Entreprise', + supervisor: 'Superviseur', + isSupervisor: 'Est un superviseur', + hours_bank_max: 'Maximum de banque d’heures ', + onboarding: 'Date d’embauche', + offboarding: 'date de départ', + employee_number: 'Numéro d’employé (Matricule employeur D)', + regular_hours_day: 'nombre régulier d’heures par jour', + address: 'Adresse', + verifiedAccountStatus: 'Compte vérifié', + unVerifiedAccountStatus: 'Compte non vérifié', + password: 'Nouveau mot de passe', + confirmedPassword: 'Confirmez votre mot de passe', + submit: 'Créer', + //Form Validaiton + firstNameValidation: 'Le prénom doit être rempli.', + lastNameValidation: 'Le nom de famille doit être rempli.', + emailValidation: 'Email doit être un e-mail valide.', + phoneNumberValidation: 'Numéro de téléphone doit être rempli.', + typeValidation: 'Type doit être rempli.', + roleValidation: 'Role doit être rempli.', + job_titleValidation: 'Le Titre d’emploi doit être rempli.', + companyValidation: 'Entreprise doit être rempli.', + supervisorValidation: 'Superviseur doit être rempli.', + hours_bank_maxValidation: 'Maximum de banque d’heures doit être rempli.', + onboardingValidation: 'Date d’embauche doit être rempli.', + employee_numberValidation: 'Numéro d’employé doit être rempli.', + regular_hours_dayValidation: + 'nombre régulier d’heures par jour doit être rempli.', + addressValidation: 'Adresse doit être rempli.', + passwordValidation: 'Le mot de passe doit répondre à tous les critères.', + confirmPasswordValidation: + 'Le mot de passe doit correspondre au nouveau mot de passe.', + }, + pagesTitles: { + newUserPageTitle: 'Nouvel utilisateur', + updateUserPageTitle: 'Mettre à jour l’utilisateur', + timeSheetPageTitle: 'Carte de temps', + timeSheetValidationsIdPageTitle: 'Carte de temps', + }, + timeSheet: { + timeSheetTab_1: 'Quarts de travail', + timeSheetTab_2: 'Dépenses', + templateButton: 'Appliquer le modèle', + shiftTemplateTitle: 'Mettre en place votre horaire de jour', + shiftType: 'Type', + remoteShift: 'Télétravail', + shiftStartTime: 'Entrée', + shiftEndTime: 'Sortie', + shiftComment: 'Commentaire', + overTimeTitle: 'Heures régulières supplémentaires: ', + totalPayedHours: 'Total des heures travaillées: ', + //shiftOptions + regularShift: 'Régulier', + eveningShift: 'Soir', + emergencyShift: 'Urgence', + sickDay: 'Maladie', + vacancyDay: 'Vacances', + holiday: 'Férié', + dateRangesWeek: 'Semaine du', + dateRangesTo: 'au', + shiftBankedHours: 'Totale d’heures à banquer', + bankedHoursHint_1: ' sur', + bankedHoursHint_2: ' heures d’accumulé', + qTimeClose: 'Fermer', + saveButton: 'Enregistrer', + //shift validations + timeSheetValidated: 'Semaine validée', + timeSheetBlocked: 'Semaine bloquée', + shiftTypeValidation: 'Le type doit être rempli.', + shiftStartTimeValidation: 'Entrée doit être rempli.', + shiftEndTimeValidation: 'Sortie doit être rempli.', + endTimeValidation: + 'L’heure de fin ne peut pas être antérieure ou égale à l’heure de début', + + expensesTile: 'Dépenses du jour', + expensesType: 'Type', + expensesValue: 'Montant', + expensesDescription: 'Description', + expensesEvidence: 'Attachement', + //expenses validations + expensesTypeValidation: 'Type doit être rempli.', + expensesValueValidation: 'Montant doit être rempli.', + //expensesOptions + refund: 'Remboursement ', + garde: 'Garde', + perdiem: 'Perdiem', + mileage: 'Kilometrage', + }, + 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', + 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é', + showAllCheckbox: 'Afficher tous', + accumulatedSicknessTotal: 'Accumulées de maladies', + consumedSicknessTotal: 'Consommées de maladies', + accumulatedVacationTotal: 'Accumulées de vacances', + consumedVacationTotal: 'Consommées de vacances', + maxVacationPerYear: 'Maximum de vacances par année', + accumulatedSicknessTotalValidation: + 'Accumulées de maladies doit être positive.', + consumedSicknessTotalValidation: + 'Consommées de maladies doit être positive.', + accumulatedVacationTotalValidation: + 'Accumulées de vacances doit être positive.', + consumedVacationTotalValidation: + 'Consommées de vacances doit être positive.', + maxVacationPerYearValidation: + 'Le nombre maximum de vacances par an doit être positif.', + resteVacationTotal: 'Reste des vacances', + validateToolTip: 'Valider', + unvalidateToolTip: 'Invalider', + lockToolTip: 'Verrouiller la semaine', + unlockToolTip: 'Déverrouiller la semaine', + }, + shiftColumns: { + title: 'Quarts de travail', + column_1: 'Type', + column_2: 'Entrée', + column_3: 'Sortie', + column_4: 'Commentaire', + column_5: 'État', + column_6: 'Rapport du superviseur', + }, + expenseColumns: { + title: 'Dépenses', + column_1: 'Type', + column_2: 'Montant', + column_3: 'Attachement', + column_4: 'Description', + column_5: 'État', + column_6: 'Rapport du superviseur', + }, + table: { + recordsTitle: 'Enregistrements par page:', + noResultsLabel: 'Le filtre n’a révélé aucun résultat', + noDataLabel: 'Je n’ai rien trouvé pour toi', + }, + autoLogout: { + title: 'Alerte', + message_start: 'Attention : vous serez automatiquement déconnecté dans', + message_end: 'secondes si vous n’interagissez pas avec l’écran.', + }, + daysOfWeek: { + Sunday: 'dimanche', + Monday: 'lundi', + Tuesday: 'mardi', + Wednesday: 'mercredi', + Thursday: 'jeudi', + Friday: 'vendredi', + Saturday: 'samedi', + }, + shiftsTemplate: { + tabTitle1: 'Quarts de travail', + tabTitle2: 'Modèles de quarts de travail', + saveButton: 'Enregistrer', + emptyShiftsMessage: 'Aucun modèle disponible.', + emptyTemplateMessage: 'Aucun quarts de travail disponible.', + selectTemplate: 'Sélectionnez un modèle', + selectTemplateNoResult: 'Aucun modele disponible.', + selectDay: 'Jour', + startTime: 'Heure de début', + endTime: 'Heure de fin', + templateTitle: 'Titre', + templateDescription: 'Description', + createButton: 'Créer', + updateButton: 'Mettre à jour', + deleteButton: 'Supprimer', + resetButton: 'Réinitialiser', + dayValidation: 'Jour doit être rempli.', + startTimeValidation: 'Heure de début doit être rempli.', + endTimeValidation: 'Heure de fin doit être rempli.', + startTimeAfterEndTimeValidation: + 'L’heure de début ne peut pas être après l’heure de fin', + endTimeBeforeStartTimeValidation: + 'L’heure de fin ne peut pas être précédente à l’heure de debut', + existingTimeShift: 'Ce temps est déjà utilisé', + }, +}; diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 3f84413..b5806d9 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -1,5 +1,7 @@ import enCA from './en-ca'; +import frCA from './fr-ca'; export default { - 'en-ca': enCA + 'en-ca': enCA, + 'fr-ca': frCA, }; diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue deleted file mode 100644 index f5c9b35..0000000 --- a/src/layouts/MainLayout.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - diff --git a/src/layouts/main-layout.vue b/src/layouts/main-layout.vue new file mode 100644 index 0000000..4ac674b --- /dev/null +++ b/src/layouts/main-layout.vue @@ -0,0 +1,15 @@ + + + \ No newline at end of file diff --git a/src/modules/auth/auth-store.ts b/src/modules/auth/auth-store.ts index 429a120..e29d244 100644 --- a/src/modules/auth/auth-store.ts +++ b/src/modules/auth/auth-store.ts @@ -1,5 +1,6 @@ +/* eslint-disable */ import { defineStore } from "pinia"; -import router from "src/modules/router"; +import router from "src/router"; import { api } from "src/boot/axios"; import { User } from "src/modules/users/types/user-interface"; import { AuthState } from "./types/auth-interface"; diff --git a/src/modules/auth/composables/use-auth-access.ts b/src/modules/auth/composables/use-auth-access.ts index 811d99a..58d05ab 100644 --- a/src/modules/auth/composables/use-auth-access.ts +++ b/src/modules/auth/composables/use-auth-access.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { useAuthStore } from "src/modules/auth/auth-store"; export const useAuthAccess = () => { diff --git a/src/modules/auth/composables/use-auth-session.ts b/src/modules/auth/composables/use-auth-session.ts index 7f3abbe..01895a7 100644 --- a/src/modules/auth/composables/use-auth-session.ts +++ b/src/modules/auth/composables/use-auth-session.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { useAuthStore } from "src/modules/auth/auth-store"; export const useAuthSession = () => { diff --git a/src/modules/auth/services/services-auth.ts b/src/modules/auth/services/services-auth.ts index 9e7a54e..7d4b355 100644 --- a/src/modules/auth/services/services-auth.ts +++ b/src/modules/auth/services/services-auth.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { api } from 'src/boot/axios'; export const AuthService = { diff --git a/src/modules/auth/types/auth-interface.ts b/src/modules/auth/types/auth-interface.ts index e1bc12c..c27df68 100644 --- a/src/modules/auth/types/auth-interface.ts +++ b/src/modules/auth/types/auth-interface.ts @@ -1,4 +1,4 @@ -import { User } from "src/modules/users/types/user-interface"; +import type { User } from "src/modules/users/types/user-interface"; export interface AuthState { token: string; diff --git a/src/modules/dashboard/components/_shared/dashboard-user-card.vue b/src/modules/dashboard/components/_shared/dashboard-container-user-card.vue similarity index 100% rename from src/modules/dashboard/components/_shared/dashboard-user-card.vue rename to src/modules/dashboard/components/_shared/dashboard-container-user-card.vue diff --git a/src/modules/dashboard/components/_shared/dashboard-user-menu.vue b/src/modules/dashboard/components/_shared/dashboard-container-user-menu.vue similarity index 100% rename from src/modules/dashboard/components/_shared/dashboard-user-menu.vue rename to src/modules/dashboard/components/_shared/dashboard-container-user-menu.vue diff --git a/src/modules/dashboard/components/_shared/dashboard.vue b/src/modules/dashboard/components/_shared/dashboard-container.vue similarity index 100% rename from src/modules/dashboard/components/_shared/dashboard.vue rename to src/modules/dashboard/components/_shared/dashboard-container.vue diff --git a/src/modules/timesheets/components/employee-timesheet-container.vue b/src/modules/timesheets/components/expenses/time-sheet-expenses-list-row.vue similarity index 100% rename from src/modules/timesheets/components/employee-timesheet-container.vue rename to src/modules/timesheets/components/expenses/time-sheet-expenses-list-row.vue diff --git a/src/modules/timesheets/components/expenses/expenses-list-row.vue b/src/modules/timesheets/components/expenses/time-sheet-expenses-list.vue similarity index 100% rename from src/modules/timesheets/components/expenses/expenses-list-row.vue rename to src/modules/timesheets/components/expenses/time-sheet-expenses-list.vue diff --git a/src/modules/timesheets/components/expenses/expenses-list.vue b/src/modules/timesheets/components/expenses/time-sheet-expenses.vue similarity index 100% rename from src/modules/timesheets/components/expenses/expenses-list.vue rename to src/modules/timesheets/components/expenses/time-sheet-expenses.vue diff --git a/src/modules/timesheets/components/expenses/expenses.vue b/src/modules/timesheets/components/shift/time-sheet-shift-list-item.vue similarity index 100% rename from src/modules/timesheets/components/expenses/expenses.vue rename to src/modules/timesheets/components/shift/time-sheet-shift-list-item.vue diff --git a/src/modules/timesheets/components/shift/shift-list-item.vue b/src/modules/timesheets/components/shift/time-sheet-shift-list.vue similarity index 100% rename from src/modules/timesheets/components/shift/shift-list-item.vue rename to src/modules/timesheets/components/shift/time-sheet-shift-list.vue diff --git a/src/modules/timesheets/components/shift/shift-list.vue b/src/modules/timesheets/components/shift/time-sheet-shift.vue similarity index 100% rename from src/modules/timesheets/components/shift/shift-list.vue rename to src/modules/timesheets/components/shift/time-sheet-shift.vue diff --git a/src/modules/timesheets/components/shift/shift.vue b/src/modules/timesheets/components/time-sheet-employee-container.vue similarity index 100% rename from src/modules/timesheets/components/shift/shift.vue rename to src/modules/timesheets/components/time-sheet-employee-container.vue diff --git a/src/modules/timesheets/components/timesheet/timesheet-shift-list-row.vue b/src/modules/timesheets/components/timesheet/time-sheet-shift-list-row.vue similarity index 100% rename from src/modules/timesheets/components/timesheet/timesheet-shift-list-row.vue rename to src/modules/timesheets/components/timesheet/time-sheet-shift-list-row.vue diff --git a/src/modules/timesheets/components/timesheet/timesheet-shift-list.vue b/src/modules/timesheets/components/timesheet/time-sheet-shift-list.vue similarity index 100% rename from src/modules/timesheets/components/timesheet/timesheet-shift-list.vue rename to src/modules/timesheets/components/timesheet/time-sheet-shift-list.vue diff --git a/src/modules/timesheets/components/timesheet/timesheet.vue b/src/modules/timesheets/components/timesheet/time-sheet.vue similarity index 100% rename from src/modules/timesheets/components/timesheet/timesheet.vue rename to src/modules/timesheets/components/timesheet/time-sheet.vue diff --git a/src/modules/users/components/_shared/user-add.vue b/src/modules/timesheets/pages/timesheet-temp-page.vue similarity index 100% rename from src/modules/users/components/_shared/user-add.vue rename to src/modules/timesheets/pages/timesheet-temp-page.vue diff --git a/src/modules/users/components/_shared/user-update.vue b/src/modules/users/components/_shared/user-container-add.vue similarity index 100% rename from src/modules/users/components/_shared/user-update.vue rename to src/modules/users/components/_shared/user-container-add.vue diff --git a/src/modules/users/components/_shared/user.vue b/src/modules/users/components/_shared/user-container-update.vue similarity index 100% rename from src/modules/users/components/_shared/user.vue rename to src/modules/users/components/_shared/user-container-update.vue diff --git a/src/modules/users/components/supervisor/supervisor-staff-profile-list-item.vue b/src/modules/users/components/_shared/user-container.vue similarity index 100% rename from src/modules/users/components/supervisor/supervisor-staff-profile-list-item.vue rename to src/modules/users/components/_shared/user-container.vue diff --git a/src/modules/users/components/supervisor/supervisor-staff-profile-list.vue b/src/modules/users/components/supervisor/supervisor-crew-profile-list-item.vue similarity index 100% rename from src/modules/users/components/supervisor/supervisor-staff-profile-list.vue rename to src/modules/users/components/supervisor/supervisor-crew-profile-list-item.vue diff --git a/src/modules/users/components/supervisor/supervisor-staff.vue b/src/modules/users/components/supervisor/supervisor-crew-profile-list.vue similarity index 100% rename from src/modules/users/components/supervisor/supervisor-staff.vue rename to src/modules/users/components/supervisor/supervisor-crew-profile-list.vue diff --git a/src/pages/help.vue b/src/modules/users/components/supervisor/supervisor-crew.vue similarity index 100% rename from src/pages/help.vue rename to src/modules/users/components/supervisor/supervisor-crew.vue diff --git a/src/pages/error.vue b/src/pages/error-page.vue similarity index 93% rename from src/pages/error.vue rename to src/pages/error-page.vue index 4227d8d..bc41d10 100644 --- a/src/pages/error.vue +++ b/src/pages/error-page.vue @@ -1,3 +1,7 @@ + + - - + \ No newline at end of file diff --git a/src/pages/footer-bars/footer-bar-mobile.vue b/src/pages/footer-bars/footer-bar-mobile.vue index eff9296..defb2d0 100644 --- a/src/pages/footer-bars/footer-bar-mobile.vue +++ b/src/pages/footer-bars/footer-bar-mobile.vue @@ -1,9 +1,9 @@ diff --git a/src/pages/index.vue b/src/pages/help-page.vue similarity index 100% rename from src/pages/index.vue rename to src/pages/help-page.vue diff --git a/src/pages/nav-bars/nav-bar-mobile.vue b/src/pages/nav-bars/nav-bar-mobile.vue index bd32651..b612e58 100644 --- a/src/pages/nav-bars/nav-bar-mobile.vue +++ b/src/pages/nav-bars/nav-bar-mobile.vue @@ -1,11 +1,12 @@ + - - + \ No newline at end of file diff --git a/src/pages/nav-bars/nav-bar.vue b/src/pages/nav-bars/nav-bar.vue index 0dacff5..24cfa23 100644 --- a/src/pages/nav-bars/nav-bar.vue +++ b/src/pages/nav-bars/nav-bar.vue @@ -1,12 +1,12 @@ diff --git a/src/pages/test-page.vue b/src/pages/test-page.vue new file mode 100644 index 0000000..b5cd91a --- /dev/null +++ b/src/pages/test-page.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/quasar.d.ts b/src/quasar.d.ts index 26103a5..d7818b0 100644 --- a/src/quasar.d.ts +++ b/src/quasar.d.ts @@ -1,5 +1,3 @@ -/* eslint-disable */ - // Forces TS to apply `@quasar/app-vite` augmentations of `quasar` package // Removing this would break `quasar/wrappers` imports as those typings are declared // into `@quasar/app-vite` diff --git a/src/router/routes.ts b/src/router/routes.ts index 1dbaa36..d82eb8f 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -3,15 +3,15 @@ import type { RouteRecordRaw } from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/', - component: () => import('layouts/MainLayout.vue'), - children: [{ path: '', component: () => import('pages/IndexPage.vue') }], + component: () => import('src/layouts/main-layout.vue'), + children: [{ path: '', component: () => import('src/pages/test-page.vue') }], }, // Always leave this as last one, // but you can also remove it { path: '/:catchAll(.*)*', - component: () => import('pages/ErrorNotFound.vue'), + component: () => import('src/pages/error-page.vue'), }, ]; diff --git a/src/shared/components/language-switch.vue b/src/shared/components/language-switch.vue index e69de29..8113faf 100644 --- a/src/shared/components/language-switch.vue +++ b/src/shared/components/language-switch.vue @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/stores/store-flag.d.ts b/src/stores/store-flag.d.ts index 683e459..f516596 100644 --- a/src/stores/store-flag.d.ts +++ b/src/stores/store-flag.d.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ // THIS FEATURE-FLAG FILE IS AUTOGENERATED, // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING import 'quasar/dist/types/feature-flag'; diff --git a/src/utils/deep-equal.ts b/src/utils/deep-equal.ts index c32afdf..352cce9 100644 --- a/src/utils/deep-equal.ts +++ b/src/utils/deep-equal.ts @@ -1,29 +1,28 @@ -export const deepEqual = (o1: any, o2: any) => { - if (o1 === o2) { +export const deepEqual = (a: unknown, b: unknown): boolean => { + if (a === b) { return true; } if ( - o1 == null || - o2 == null || - typeof o1 !== 'object' || - typeof o2 !== 'object' + a == null || // handles null and undefined + b == null || + typeof a !== 'object' || + typeof b !== 'object' ) { return false; } - const keys1 = Object.keys(o1); - const keys2 = Object.keys(o2); + const aKeys = Object.keys(a as Record); + const bKeys = Object.keys(b as Record); - if (keys1.length !== keys2.length) { + if (aKeys.length !== bKeys.length) { return false; } - for (const key of keys1) { - if (!deepEqual(o1[key], o2[key])) { - return false; - } - } - - return true; -}; \ No newline at end of file + return aKeys.every((key) => + deepEqual( + (a as Record)[key], + (b as Record)[key] + ) + ); +};