diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9ec98a1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Step 1 - Building the app +FROM node:22 AS build +WORKDIR /app +COPY package*.json ./ +# Set environment variables +ARG BACKEND_URL +ENV VITE_TARGO_BACKEND_URL=$BACKEND_URL +# Install dependencies +RUN npm install -g @quasar/cli +COPY . . +RUN npm install +RUN npm run build + +# Step 2 - Move Applicatin to Nginx +FROM nginx:alpine +COPY --from=build /app/dist/spa /usr/share/nginx/html +RUN mkdir /usr/share/nginx/html/src +COPY --from=build /app/src /usr/share/nginx/html/src +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..f09bd4c --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,26 @@ +--- +name: app-targo +services: + backend: + build: + context: https://git.targo.ca/Targo/targo_backend.git + args: + - CALLBACK_URL=http://${SERVER_IP}:${BACKEND_PUBLIC_PORT}/auth/callback + environment: + - REDIRECT_URL_DEV=http://${SERVER_IP}:${FRONTEND_PUBLIC_PORT}/#/login-success + env_file: + - stack.env + ports: + - ${BACKEND_PUBLIC_PORT}:3000 + + frontend: + build: + context: https://git.targo.ca/Targo/targo_frontend.git + args: + - BACKEND_URL=http://${SERVER_IP}:${BACKEND_PUBLIC_PORT}/ + volumes: + - .:/app + env_file: + - stack.env + ports: + - ${FRONTEND_PUBLIC_PORT}:80 \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index 2498ecb..e1caa74 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -41,6 +41,11 @@ export default defineConfigWithVueTs( 'error', { prefer: 'type-imports' } ], + "no-unused-vars": "off", + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_' } + ], } }, // https://github.com/vuejs/eslint-config-typescript @@ -63,15 +68,15 @@ export default defineConfigWithVueTs( } }, + files: ['**/*.ts', '**/*.vue'], + // add your custom rules here rules: { 'prefer-promise-reject-errors': 'off', // warn about unused but underscored variables - 'no-unused-vars': [ - 'warn', - { argsIgnorePattern: '^_' } - ], + + 'no-unused-vars': 'off', // allow debugger during development only 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' diff --git a/quasar.config.ts b/quasar.config.ts index 5ae469f..8e9ee05 100644 --- a/quasar.config.ts +++ b/quasar.config.ts @@ -29,11 +29,12 @@ export default defineConfig((ctx) => { // 'fontawesome-v6', // 'eva-icons', // 'themify', - // 'line-awesome', + 'line-awesome', + 'material-icons', + 'material-icons-outlined', + + 'roboto-font', // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! - - 'roboto-font', // optional, you are not bound to it - 'material-icons', // optional, you are not bound to it ], // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#build @@ -97,6 +98,7 @@ export default defineConfig((ctx) => { devServer: { // https: true, open: true, // opens browser window automatically + allowedHosts: true, }, // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#framework @@ -104,9 +106,8 @@ export default defineConfig((ctx) => { config: { notify: { color: 'primary', - avatar: 'https://cdn.quasar.dev/img/boy-avatar.png', }, - dark: false, + dark: 'auto', }, // iconSet: 'material-icons', // Quasar icon set diff --git a/src/App.vue b/src/App.vue index dfc3050..337fe3b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,9 @@ - \ No newline at end of file diff --git a/src/assets/en-CA.png b/src/assets/en-CA.png new file mode 100644 index 0000000..cd42ab8 Binary files /dev/null and b/src/assets/en-CA.png differ diff --git a/src/assets/facturation_thumbnail.png b/src/assets/facturation_thumbnail.png new file mode 100644 index 0000000..b312a2a Binary files /dev/null and b/src/assets/facturation_thumbnail.png differ diff --git a/src/assets/fr-FR.png b/src/assets/fr-FR.png new file mode 100644 index 0000000..cb902f7 Binary files /dev/null and b/src/assets/fr-FR.png differ diff --git a/src/assets/google_thumbnail.png b/src/assets/google_thumbnail.png new file mode 100644 index 0000000..7ca64d8 Binary files /dev/null and b/src/assets/google_thumbnail.png differ diff --git a/src/assets/help-ss/access-management.png b/src/assets/help-ss/access-management.png new file mode 100644 index 0000000..64b95e0 Binary files /dev/null and b/src/assets/help-ss/access-management.png differ diff --git a/src/assets/help-ss/calendar.png b/src/assets/help-ss/calendar.png new file mode 100644 index 0000000..254b572 Binary files /dev/null and b/src/assets/help-ss/calendar.png differ diff --git a/src/assets/help-ss/commenting-shift-overview.png b/src/assets/help-ss/commenting-shift-overview.png new file mode 100644 index 0000000..777ab71 Binary files /dev/null and b/src/assets/help-ss/commenting-shift-overview.png differ diff --git a/src/assets/help-ss/commenting-shift.png b/src/assets/help-ss/commenting-shift.png new file mode 100644 index 0000000..1d4a7e1 Binary files /dev/null and b/src/assets/help-ss/commenting-shift.png differ diff --git a/src/assets/help-ss/create-employee.png b/src/assets/help-ss/create-employee.png new file mode 100644 index 0000000..c225a7a Binary files /dev/null and b/src/assets/help-ss/create-employee.png differ diff --git a/src/assets/help-ss/create-shift-overview.png b/src/assets/help-ss/create-shift-overview.png new file mode 100644 index 0000000..9b806ef Binary files /dev/null and b/src/assets/help-ss/create-shift-overview.png differ diff --git a/src/assets/help-ss/create-shift.png b/src/assets/help-ss/create-shift.png new file mode 100644 index 0000000..cf89658 Binary files /dev/null and b/src/assets/help-ss/create-shift.png differ diff --git a/src/assets/help-ss/dashboard.png b/src/assets/help-ss/dashboard.png new file mode 100644 index 0000000..8994075 Binary files /dev/null and b/src/assets/help-ss/dashboard.png differ diff --git a/src/assets/help-ss/default-dashboard.png b/src/assets/help-ss/default-dashboard.png new file mode 100644 index 0000000..30aae90 Binary files /dev/null and b/src/assets/help-ss/default-dashboard.png differ diff --git a/src/assets/help-ss/default-employee-list.png b/src/assets/help-ss/default-employee-list.png new file mode 100644 index 0000000..659ab37 Binary files /dev/null and b/src/assets/help-ss/default-employee-list.png differ diff --git a/src/assets/help-ss/default-employee-management.png b/src/assets/help-ss/default-employee-management.png new file mode 100644 index 0000000..a130bee Binary files /dev/null and b/src/assets/help-ss/default-employee-management.png differ diff --git a/src/assets/help-ss/default-personnal_profile.png b/src/assets/help-ss/default-personnal_profile.png new file mode 100644 index 0000000..290b501 Binary files /dev/null and b/src/assets/help-ss/default-personnal_profile.png differ diff --git a/src/assets/help-ss/default-timesheet.png b/src/assets/help-ss/default-timesheet.png new file mode 100644 index 0000000..21451b8 Binary files /dev/null and b/src/assets/help-ss/default-timesheet.png differ diff --git a/src/assets/help-ss/default-validation-page.png b/src/assets/help-ss/default-validation-page.png new file mode 100644 index 0000000..b06da43 Binary files /dev/null and b/src/assets/help-ss/default-validation-page.png differ diff --git a/src/assets/help-ss/delete-expense.png b/src/assets/help-ss/delete-expense.png new file mode 100644 index 0000000..ffa4f59 Binary files /dev/null and b/src/assets/help-ss/delete-expense.png differ diff --git a/src/assets/help-ss/delete-shift.png b/src/assets/help-ss/delete-shift.png new file mode 100644 index 0000000..f3e8e77 Binary files /dev/null and b/src/assets/help-ss/delete-shift.png differ diff --git a/src/assets/help-ss/employee-list-grid.png b/src/assets/help-ss/employee-list-grid.png new file mode 100644 index 0000000..fce4f85 Binary files /dev/null and b/src/assets/help-ss/employee-list-grid.png differ diff --git a/src/assets/help-ss/employee-list.png b/src/assets/help-ss/employee-list.png new file mode 100644 index 0000000..02541c6 Binary files /dev/null and b/src/assets/help-ss/employee-list.png differ diff --git a/src/assets/help-ss/expenses.png b/src/assets/help-ss/expenses.png new file mode 100644 index 0000000..a2fa886 Binary files /dev/null and b/src/assets/help-ss/expenses.png differ diff --git a/src/assets/help-ss/personal_infos.png b/src/assets/help-ss/personal_infos.png new file mode 100644 index 0000000..89c0ba3 Binary files /dev/null and b/src/assets/help-ss/personal_infos.png differ diff --git a/src/assets/help-ss/preferences.png b/src/assets/help-ss/preferences.png new file mode 100644 index 0000000..08c87ce Binary files /dev/null and b/src/assets/help-ss/preferences.png differ diff --git a/src/assets/help-ss/professionnal_infos.png b/src/assets/help-ss/professionnal_infos.png new file mode 100644 index 0000000..5a976ea Binary files /dev/null and b/src/assets/help-ss/professionnal_infos.png differ diff --git a/src/assets/help-ss/schedule-preset-management.png b/src/assets/help-ss/schedule-preset-management.png new file mode 100644 index 0000000..afa5158 Binary files /dev/null and b/src/assets/help-ss/schedule-preset-management.png differ diff --git a/src/assets/help-ss/search-bar.png b/src/assets/help-ss/search-bar.png new file mode 100644 index 0000000..735c018 Binary files /dev/null and b/src/assets/help-ss/search-bar.png differ diff --git a/src/assets/help-ss/terminated-employee-list.png b/src/assets/help-ss/terminated-employee-list.png new file mode 100644 index 0000000..b16b811 Binary files /dev/null and b/src/assets/help-ss/terminated-employee-list.png differ diff --git a/src/assets/help-ss/timesheet-appovals-list.png b/src/assets/help-ss/timesheet-appovals-list.png new file mode 100644 index 0000000..8dcd3bb Binary files /dev/null and b/src/assets/help-ss/timesheet-appovals-list.png differ diff --git a/src/assets/help-ss/timesheet-approvals.png b/src/assets/help-ss/timesheet-approvals.png new file mode 100644 index 0000000..d9c6c3c Binary files /dev/null and b/src/assets/help-ss/timesheet-approvals.png differ diff --git a/src/assets/help-ss/timesheet-details.png b/src/assets/help-ss/timesheet-details.png new file mode 100644 index 0000000..b60e4ee Binary files /dev/null and b/src/assets/help-ss/timesheet-details.png differ diff --git a/src/assets/help-ss/timesheets.png b/src/assets/help-ss/timesheets.png new file mode 100644 index 0000000..9042866 Binary files /dev/null and b/src/assets/help-ss/timesheets.png differ diff --git a/src/assets/help-ss/update-employee.png b/src/assets/help-ss/update-employee.png new file mode 100644 index 0000000..6d89b41 Binary files /dev/null and b/src/assets/help-ss/update-employee.png differ diff --git a/src/assets/help-ss/update-expense.png b/src/assets/help-ss/update-expense.png new file mode 100644 index 0000000..9d60290 Binary files /dev/null and b/src/assets/help-ss/update-expense.png differ diff --git a/src/assets/help-ss/update-shift.png b/src/assets/help-ss/update-shift.png new file mode 100644 index 0000000..a653aa9 Binary files /dev/null and b/src/assets/help-ss/update-shift.png differ diff --git a/src/assets/info-pannes.png b/src/assets/info-pannes.png new file mode 100644 index 0000000..fcfe362 Binary files /dev/null and b/src/assets/info-pannes.png differ diff --git a/src/assets/login-background.png b/src/assets/login-background.png index f234c90..82d0429 100644 Binary files a/src/assets/login-background.png and b/src/assets/login-background.png differ diff --git a/src/assets/map_targo_banner.png b/src/assets/map_targo_banner.png new file mode 100644 index 0000000..3077661 Binary files /dev/null and b/src/assets/map_targo_banner.png differ diff --git a/src/assets/targo_building.png b/src/assets/targo_building.png new file mode 100644 index 0000000..8f4fafc Binary files /dev/null and b/src/assets/targo_building.png differ diff --git a/src/assets/targo_help_banner.png b/src/assets/targo_help_banner.png new file mode 100644 index 0000000..be0c2b5 Binary files /dev/null and b/src/assets/targo_help_banner.png differ diff --git a/src/assets/village.png b/src/assets/village.png index 7b6ead1..5d8da3f 100644 Binary files a/src/assets/village.png and b/src/assets/village.png differ diff --git a/src/boot/axios.ts b/src/boot/axios.ts index 0ad51d2..3ac8c4c 100644 --- a/src/boot/axios.ts +++ b/src/boot/axios.ts @@ -2,10 +2,10 @@ import { defineBoot } from '#q-app/wrappers'; import axios, { type AxiosInstance } from 'axios'; declare module 'vue' { - interface ComponentCustomProperties { - $axios: AxiosInstance; - $api: AxiosInstance; - } + interface ComponentCustomProperties { + $axios: AxiosInstance; + $api: AxiosInstance; + } } // Be careful when using SSR for cross-request state pollution @@ -14,18 +14,21 @@ declare module 'vue' { // good idea to move this instance creation inside of the // "export default () => {}" function below (which runs individually // for each client) -const api = axios.create({ baseURL: import.meta.env.VITE_TARGO_BACKEND_AUTH_URL }); +const api = axios.create({ + baseURL: import.meta.env.VITE_TARGO_BACKEND_URL, + withCredentials: true +}); export default defineBoot(({ app }) => { - // for use inside Vue files (Options API) through this.$axios and this.$api + // for use inside Vue files (Options API) through this.$axios and this.$api - app.config.globalProperties.$axios = axios; - // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) - // so you won't necessarily have to import axios in each vue file + app.config.globalProperties.$axios = axios; + // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) + // so you won't necessarily have to import axios in each vue file - app.config.globalProperties.$api = api; - // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) - // so you can easily perform requests against your app's API + app.config.globalProperties.$api = api; + // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) + // so you can easily perform requests against your app's API }); export { api }; diff --git a/src/css/app.scss b/src/css/app.scss index adfa295..f5b3f6e 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -1,11 +1,10 @@ // app global css in SCSS form -@each $size in (1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 75, 100) { +@each $size in (1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 75, 100, 200) { .rounded-#{$size} { border-radius: #{$size}px !important; - } + } } - .text-fb-blue { color: #4267B2 !important; } @@ -25,11 +24,53 @@ } body.body--dark { - --q-secondary: #0f1114; + --q-secondary: #151520; color: $grey-2; } .body--light { --q-dark: #FFF; color: $blue-grey-8; +} + +.shift-highlight { + background: #0195462a; +} + +.frosted-glass { + background-color: #0008 !important; + backdrop-filter: blur(5px); +} + +.q-btn--push::before { + border-bottom: 4px solid rgba(0,0,0, 0.25); +} + +.q-btn--push:active { + transform: translateY(3px); +} + +.q-btn--push:active::before { + border-bottom-width: 1px; +} + +/* Chrome, Safari, Edge, Opera */ +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +input[type=number] { + -moz-appearance: textfield; +} + +.q-field--dark .q-field__control::before { + border-color: #fff3; +} + +.q-field--dark .q-field__control:hover::before, .q-field--outlined .q-field__control:hover::before { + border-color: var(--q-accent); + border-width: 2px; } \ No newline at end of file diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 2131a9e..1b60238 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -12,21 +12,29 @@ // to match your app's branding. // Tip: Use the "Theme Builder" on Quasar's documentation website. -$primary : #019547; +$primary : #30303A; $secondary : #DAE0E7; -$accent : #AAD5C4; +$accent : #0c9a3b; +$accent2 : #0a7d32; -$dark-shadow-color : #019547; +$dark-shadow-color : #000000; -$elevation-dark-umbra : rgba($dark-shadow-color, 0.4); -$elevation-dark-penumbra : rgba($dark-shadow-color, 0); -$elevation-dark-ambient : rgba($dark-shadow-color, 0); +$elevation-dark-umbra : rgba($dark-shadow-color, 1); +$elevation-dark-penumbra : rgba($dark-shadow-color, 0.75); +$elevation-dark-ambient : rgba($dark-shadow-color, 0.53); -$dark-shadow-2 : 0 3px 5px -1px $elevation-dark-umbra, 0 5px 8px $elevation-dark-penumbra, 0 1px 14px $elevation-dark-ambient; -$layout-shadow-dark : 0 0 10px 5px rgba($dark-shadow-color, 0.5); +$dark-shadow-2 : 2px 3px $elevation-dark-umbra, 2px 3px 6px $elevation-dark-penumbra, 2px 3px 14px $elevation-dark-ambient; +$layout-shadow-dark : 0 0 5px 5px rgba($dark-shadow-color, 0.5); -$dark : #333; -$dark-page : #343434; +$input-text-color : #455A64; +$input-autofill-color : #AAD5C4; +$field-dense-label-top : 5px !default; +$field-dense-label-font-size : 16px !default; + +$button-shadow : 0 0 0 transparent; + +$dark : #40404C; +$dark-page : #343444; $positive : #21ba45; $negative : #e6364b; diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index ce823cb..4ed3093 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -1,235 +1,472 @@ export default { - chatbot: { - chat_header: "AI Assistant", - chat_initial_message: - "Welcome to your technical assistant.\nPlease provide the Customer ID to get a diagnostic report", - chat_placeholder: "Enter a Message", - chat_thinking: "Thinking...", - }, - employee_list: { - page_header: "Employee Directory", - table: { - first_name: "First name", - last_name: "Last name", - email: "Email", - phone_number: "Phone number", - role: "Role", - supervisor: "Supervisor", - company: "Company", + chatbot: { + chat_header: "AI Assistant", + chat_initial_message: "Welcome to your technical assistant.\nPlease provide the Customer ID to get a diagnostic report", + chat_placeholder: "Enter a Message", + chat_thinking: "Thinking...", }, - }, - login: { - page_header: "account login", - email: "e-mail", - password: "password", - button: { - connect: "connect", - employee: "employee", - facebook: "Facebook", - remember_me: "remember me", + dashboard: { + carousel: { + welcome_title: "Welcome to the new Targo Application!", + welcome_message: "Development is complete and the application is live! Things have remained mostly the same, but with a new coat of paint, a more streamlined user experience, and most importantly, drastically improved security and optimization!", + help_title: "We have a help page!", + help_message: "We've modernized the app while trying to make as few functional changes as possible, but if there's ever any part of the site that leaves you scratching your head, feel free to check out the help page.", + }, + useful_links: "useful links", }, - tooltip: { - coming_soon: "coming soon!", - }, - }, - nav_bar: { - home: "homepage", - employee_list: "employee directory", - timesheet_approvals: "timesheet approvals", - timesheet: "timesheet", - profile: "profile", - help: "help", - logout: "log out", - }, + help: { + label: "Centre d'aide", + tutorial: { + dashboard: { + title: "Home Page", + news_feed: "News Feed", + chat_bot: "Technical chat-bot", + notifications: "Notifications", + }, + personal_profile: { + title: "Personnal Profile", + personal_info: "Personal informations", + professional_info: "Professional informations", + }, + timesheets: { + title: "Timesheet", + create_shift: "Add a new shift", + update_shift: "Update an existing shift", + delete_shift: "Removing a shift from the timesheet", + comment_shift: "Commenting a shift", + create_expense: "Add a new expense", + update_expense: "Update an existing expense", + delete_expense: "Removing an expense from the list", - profile: { - personal: { - tab_title: "personal", - first_name: "first name", - last_name: "last name", - phone_number: "phone number", - address: "address", - address_hint: "# address, city, region, country", - birthdate: "birthdate", + }, + employee_list: { + title: "Employee List", + terminated_employees: "Inactive employees", + }, + employee_management: { + title: "Employee Management", + create_employee: "Creating a new employee", + update_employee: "Updating an existing employee's informations", + module_access: "App managing access tool", + schedule_preset: "Schedule preset management", + terminating_employee: "terminate an employee", + }, + timesheets_approval: { + title: "Timesheets approval", + approval: "timesheet approvals", + inspect: "Inspect timesheets", + comment_expense: "Commenting an expense", + }, + shared: { + search: "Advance search", + preferences: "Display mode", + calendar: "Navigation using the calendar", + display: "Display as cards or as a list" + }, + }, }, - employee: { - tab_title: "career", - email: "e-mail", - job_title: "job title", - company: "company", - supervisor: "supervisor", - hired_date: "hiring date", + + employee_list: { + page_header: "Employee Directory", + table: { + first_name: "First name", + last_name: "Last name", + email: "Email", + phone_number: "Phone number", + role: "Role", + supervisor: "Supervisor", + company: "Company", + is_supervisor: "is a supervisor", + expected_daily_hours: "Expected Daily Hours", + active: "active", + inactive: "inactive", + }, + errors: { + first_name_required: "Employee's first name is required", + last_name_required: "Employee's last name is required", + company_required: "Employee must be assigned to a company", + phone_number_required: "Employee's phone number required", + hire_date_required: "Employee's first work day must be entered", + daily_hours_required: "Provide employee's expected daily hours worked", + no_modules_warning: "All modules disabled. This will lock the user out.", + } + }, + + employee_management: { + add_employee: "Add employee", + modify_employee: "Modify employee", + access_label: "access", + details_label: "details", + schedule_label: "schedule", + can_be_entered_later: "OPTIONAL: can be entered later", + enter_delete_input: "type 'DELETE' to remove", + banked_hours: "available banked hours", + sick_hours: "available PTO hours", + vacation_hours: "available vacation hours", + schedule_presets: { + preset_list_placeholder: "Select a schedule", + preset_name_placeholder: "schedule preset name", + delete_warning: "", + delete_warning_employee_1: "This schedule is used by", + delete_warning_employee_2: "Deleting this preset will not affect previous timesheets, but they will no longer be able to apply this preset to their timesheets going forward.", + }, + module_access: { + dashboard: "Dashboard", + employee_list: "employee list", + employee_management: "employee management", + personal_profile: "profile", + timesheets: "timesheets", + timesheets_approval: "timesheet approval", + user_access: "module access", + by_role: "by role", + by_module: "by module", + preset_admin: "administrator", + preset_employee: "employee", + uncheck_all: "remove all", + admin_description: "Check all modules", + employee_description: "Only check modules that are relevant to standard employees with no management access", + none_description: "Uncheck all modules", + usage_description: "You can use roles to enable preset modules, add or remove modules individually, or both", + }, + filter: { + hide_terminated: "Hide inactive employees", + sort_by_tags: "sort by tags", + }, }, - preferences: { - tab_title: "preferences", - display_options: "display options", - language_options: "language options", - dark_mode: "dark", - light_mode: "light", - }, - errors: { - must_enter_birthdate: "You must enter a valid birthdate", - }, - }, - shared: { error: { - no_data_found: "no data found", - no_search_results: "no results matching search", + not_found_header: "page not found", + not_found_description: "You may have entered the wrong URL, or you may not have access to this page", + go_back: "go back", }, - label: { - search: "search", - filter: "filters", - loading: "loading...", - language: "Language", - add: "ajouter", - save: "save", - remove: "remove", - cancel: "cancel", - update: "update", - modify: "modify", - close: "close", - }, - misc: { - or: "or", - and: "and", - to: "to", - from: "from", - yes: "yes", - no: "no", - in: "in", - out: "out", - }, - shift_type: { - regular: "regular", - evening: "evening", - emergency: "emergency", - overtime: "overtime", - holiday: "holiday", - vacation: "vacation", - sick: "sick", - remote: "remote work", - }, - weekday: { - sunday: "dimanche", - monday: "lundi", - tuesday: "mardi", - wednesday: "mercredi", - thursday: "jeudi", - friday: "vendredi", - saturday: "samedi", - }, - }, - timesheet: { - page_header: "Timesheet", - nav_button: { - calendar_date_picker: "Calendar", - current_week: "This week", - next_week: "Next week", - previous_week: "Previous week", + login: { + page_header: "account login", + email: "e-mail", + password: "password", + connected: "Connected", + redirecting: "Redirecting...", + button: { + connect: "connect", + employee: "employee", + facebook: "Facebook", + remember_me: "remember me", + }, + tooltip: { + coming_soon: "coming soon!", + }, + error: { + login_failed: "Failed to login", + popups_blocked: "Popups are blocked on this device", + }, }, - save_button: "Save", - cancel_button: "Cancel", - remote_button: "Remote work", - delete_button: "Delete", - shift: { - actions: { - add: "Add Shift", - edit: "Edit shift", - delete: "Delete shift", - delete_confirmation_msg: "Do you want to delete this shift completly?", - }, - types: { - label: "Shift`s Type", - EMERGENCY: "Emergency", - EVENING: "Evening", - HOLIDAY: "Holiday", - OVERTIME: "Overtime", - REGULAR: "Regular", - SICK: "Sick Leave", - VACATION: "Vacation", - REMOTE: "Remote work", - }, - errors: { - not_found: "Shift not found", - overlap: "An overlaps occured between 2 or more shifts", - invalid: "Invalid shift`s entry", - unknown: "Unknown error", - comment_required: "A comment is required", - comment_too_long: "Your comment is too long", - }, - fields: { - start: "Start (HH:mm)", - end: "End (HH:mm)", - header_comment: "Shift`s comment", - textarea_comment: "Leave a comment here", - }, - }, - expense: { - add_expense: "Add Expense", - amount: "Amount", - date: "Date", - empty_list: "No registered expenses", - employee_comment: "Comment", - supervisor_comment: "Supervisor note", - errors: { - date_required_or_invalid: "the date is missing or invalid", - comment_required: "A comment required", - comment_too_long: "Your comment is too long", - amount_must_be_positive: "the amount cannot be under 0$", - mileave_must_be_positive: "the mileage cannot be under 0", - amount_xor_mileage: - "you cannot enter an amount and a mileage for the same expense", - mileage_required_for_type: - "you need to enter a value for mileage when you enter an expense of that type", - amount_required_for_type: - "you need to enter a value for amount when you enter an expense of that type", - }, - hints: { - amount_or_mileage: "Either amount or mileage, not both", - comment_required: "A comment required", - attach_file: "Attach File", - }, - mileage: "mileage", - open_btn: "list of expenses", - title: "List of all expenses", - total_amount: "Total amount", - total_mileage: "Total mileage", - type: "Type", - types: { - PER_DIEM: "Per Diem", - EXPENSES: "expense", - MILEAGE: "mileage", - PRIME_GARDE: "on-call allowance", - }, - }, - }, - timesheet_approvals: { - page_title: "Validation cartes de temps", - table: { - full_name: "full name", - email: "email address", - expenses: "expenses", - mileage: "mileage", - verified: "approved", - unverified: "pending", + nav_bar: { + home: "homepage", + employee_list: "employee directory", + timesheet_approvals: "timesheet approvals", + timesheet: "timesheet", + profile: "profile", + help: "help", + logout: "log out", }, - chart: { - hours_worked_title: "hours worked", - expenses_title: "expenses accrued", + + profile: { + personal: { + tab_title: "personal", + first_name: "first name", + last_name: "last name", + phone_number: "phone number", + address: "address", + address_hint: "# address, city, region, country", + birthdate: "birthdate", + }, + employee: { + tab_title: "career", + email: "e-mail", + job_title: "job title", + company: "company", + supervisor: "supervisor", + hired_date: "hiring date", + fired_date: "departure date", + bankroll_id: "payroll ID", + }, + preferences: { + tab_title: "preferences", + display_options: "Color mode", + language_options: "language options", + 'fr-FR': "Français", + 'en-CA': "English", + dark_mode: "dark", + light_mode: "light", + auto_mode: "auto", + update_successful: "Preferences saved", + update_failed: "Failed to save preferences", + }, + schedule_presets: { + tab_title: "Schedule", + selected_schedule: "Selected Schedule Preset", + new_preset: "Build a new preset", + }, + errors: { + must_enter_birthdate: "You must enter a valid birthdate", + } }, - print_report: { - company: "company", - type: "type", - shifts: "shifts", - expenses: "expenses", + + shared: { + error: { + no_data_found: "no data found", + no_search_results: "no results matching search", + }, + label: { + search: "search", + filter: "filters", + loading: "loading...", + language: "Language", + add: "ajouter", + save: "save", + remove: "remove", + cancel: "cancel", + update: "update", + modify: "modify", + close: "close", + download: "download", + open: "open", + }, + misc: { + or: "or", + and: "and", + to: "to", + from: "from", + yes: "yes", + no: "no", + in: "in", + out: "out", + }, + shift_type: { + regular: "regular", + evening: "evening", + emergency: "emergency", + overtime: "overtime", + holiday: "holiday", + vacation: "vacation", + sick: "sick", + remote: "remote work", + }, + weekday: { + sun: "dimanche", + mon: "lundi", + tue: "mardi", + wed: "mercredi", + thu: "jeudi", + fri: "vendredi", + sat: "samedi", + }, }, - tooltip: { - button_detailed_view: "detailed view", + + timesheet: { + page_header: "Timesheet", + week: "week", + total_hours: "total hours: ", + total_expenses: "total expenses: ", + vacation_available: "vacation time available: ", + sick_available: "sick time available: ", + current_shifts: "shifts worked", + apply_preset: "auto-fill", + apply_preset_day: "Apply schedule to day", + apply_preset_week: "Apply schedule to week", + nav_button: { + calendar_date_picker: "Calendar", + current_week: "This week", + next_week: "Next period", + previous_week: "Previous period", + }, + shift: { + actions: { + add: "Add Shift", + edit: "Edit shift", + delete: "Delete shift", + delete_confirmation_msg: "Do you want to delete this shift completly?", + }, + types: { + label: "Shift`s Type", + EMERGENCY: "Emergency", + EVENING: "Evening", + HOLIDAY: "Holiday", + OVERTIME: "Overtime", + REGULAR: "Regular", + SICK: "Sick Leave", + VACATION: "Vacation", + REMOTE: "Remote", + OFFICE: "Office", + }, + fields: { + start: "Start (HH:mm)", + end: "End (HH:mm)", + header_comment: "Shift`s comment", + textarea_comment: "Leave a comment here", + }, + }, + expense: { + add_expense: 'Add Expense', + amount: 'Amount', + date: 'Date', + empty_list: 'No registered expenses', + employee_comment: 'Comment', + supervisor_comment: 'Supervisor note', + hints: { + amount_or_mileage: "Either amount or mileage, not both", + comment_required: "A comment required", + attach_file: "Attach File" + }, + mileage: "mileage", + open_btn: "list of expenses", + title: "List of all expenses", + total_amount: "Total amount", + total_mileage: "Total mileage", + type: "Type", + types: { + PER_DIEM: "Per Diem", + EXPENSES: "expense", + MILEAGE: "mileage", + ON_CALL: "on-call allowance", + }, + }, + errors: { + INVALID_SHIFT_TIME: "In and Out shift times are reversed", + SHIFT_OVERLAP: "An overlaps occured between 2 or more shifts", + SHIFT_OVERLAP_SHORT: "Overlap", + INVALID_SHIFT: "A shift contains missing or corrupted data", + SHIFT_TIME_REQUIRED: "Time missing", + SHIFT_TYPE_REQUIRED: "Shift type required", + SHIFT_NOT_FOUND: "Shift missing or deleted", + PAY_PERIOD_NOT_FOUND: "No pay period matching given dates", + EMPLOYEE_NOT_FOUND: "No employee matching current login details", + INVALID_TIMESHEET: "Timesheet data is missing or corrupted", + TIMESHEET_NOT_FOUND: "No timesheet found with provided data", + INVALID_EXPENSE: "An expense contains missing or corrupted data", + EXPENSE_NOT_FOUND: "No expense found with provided data", + UPDATE_ERROR: "Error while updating data", + }, }, - }, -}; + + timesheet_approvals: { + page_title: "Validation cartes de temps", + chart: { + hours_worked_title: "hours worked", + expenses_title: "expenses accrued", + }, + print_report: { + title: "Download options", + description: "Choose what to include in the report", + company: "companies", + type: "type", + shifts: "shifts", + expenses: "expenses", + options: "options", + }, + table: { + full_name: "full name", + email: "email address", + is_approved: "approval", + expenses: "expenses", + mileage: "mileage", + verified: "approved", + unverified: "pending", + inactive: "inactive", + regular: "regular", + evening: "evening", + emergency: "emergency", + overtime: "overtime", + holiday: "holiday", + vacation: "vacation", + sick: "sick", + remote: "remote work", + weekly_hours_1: "1st week hours", + weekly_hours_2: "2nd week hours", + total_hours: "total hours", + filter_active: "show only active employees", + filter_team: "show my team only", + filter_columns: "Information displayed", + }, + tooltip: { + button_detailed_view: "detailed view", + approve: "Approve", + unapprove: "remove approval", + }, + }, + + descriptions: { + dashboard: { + menu: "To access the main menu, click the button located in the upper-left corner. This menu allows you to navigate through the entire application.", + news_feed: "General announcements and important updates are displayed here. This view is the same for all employees.", + notifications: "Notifications are accessible via the bell icon located in the upper-right corner. They allow you to quickly view information relevant to you, \ + such as leave, vacation, or absence requests, overtime hours worked during the current week, \ + and comments left by your supervisor.", + chat_bot: "To access the bot, simply click on the \"bot\" bubble. The conversational bot allows you to quickly find information about a client, \ + an invoice, or a device.", + }, + personal_profile: { + personal_info: "In the \"Personal\" tab, you can view your personal information, such as your name, phone numbers, \ + address, and date of birth.", + professional_info: "In the \"Career\" tab, you can view your professional information, including your position, the name of the company you work for, \ + your supervisor's name and email address, as well as your hire date.", + preferences: "In the \"Preferences\" tab, you can adjust certain settings based on your personal preferences, such as dark mode, \ + language, and notifications.", + }, + timesheets: { + create_shift: "To add a work shift, click the green \"Add Time\" tab and enter the following required information: \ + the shift type, start time, end time, and whether the shift is on-site or remote. \ + Then click \"Save\", located in the upper-right corner of the time card.", + update_shift: "To modify a work shift, click the information you want to update, adjust the value, then click \"Save\", \ + located in the upper-right corner of the time card.", + delete_shift: "To delete a work shift, click the red trash icon associated with the entry.", + comment_shift: "To leave a comment on a work shift, click the conversation bubble icon located to the right of the shift entry, \ + then click \"Save\" in the upper-right corner of the time card.", + create_expense: "To add an expense, access the expense list using the button located in the upper-right corner. \ + You must then complete the following fields: the date (today's date is selected by default), the expense type, \ + the amount or mileage, a comment justifying the expense, and attach a supporting document. \ + Then click the \"Add\" button.", + update_expense: "To modify an expense, access the expense list, select the expense you wish to edit, make the necessary changes, \ + then click \"Update\" to save.", + delete_expense: "To delete an expense, access the expense list and click the red trash icon.", + }, + employee_list: { + terminated_employees: "This option allows you to show or hide employees who are no longer employed.", + }, + employee_management: { + create_employee: "To create an employee, access the \"Add Employee\" menu located in the upper-left corner of the employee list. \ + In the \"Details\" tab, first enter all required information, excluding the termination date. \ + Then assign the appropriate access rights to the employee. Optionally, you may assign a preset schedule. \ + Click \"Save\" to confirm the employee creation.", + update_employee: "To update an employee's information, access rights, or schedule, select the employee's profile and navigate to the appropriate tab. \ + Make the necessary changes, then click \"Update\" to confirm.", + module_access: "To manage access to different parts of the application, select the desired employee's profile and navigate to the \"Access\" tab. \ + Two selection options are available: by role or by module. If the employee is a supervisor, the \"Administrator\" role is recommended. \ + For a standard employee, the \"Employee\" role is appropriate. Specific modules can also be selected in special cases.", + schedule_preset: "To assign, modify, or create a schedule for an employee, first select the employee, then navigate to the \"Schedule\" tab in the edit menu. \ + You may select an existing schedule, create a new one by assigning a unique name, or copy an existing schedule, modify it, and rename it. \ + Once satisfied, click \"Update\" to confirm your selection.", + terminating_employee: "To terminate an employee, select the employee's profile (or row). Once the edit menu is displayed, \ + enter the termination date and click \"Update\".", + }, + timesheets_approval: { + approval: "To approve a timesheet, click the bottom of the card where the lock icon is located. In list view, \ + click the lock icon on the right side of the corresponding row.", + inspect: "To review an employee's work shifts or expenses, click the briefcase icon located in the upper-right corner. \ + You will find statistics on hours worked as well as expenses incurred. Within this window, you may edit work shifts \ + and expenses. Click \"Save\" to confirm the changes.", + comment_expense: "To leave a comment on an expense submitted by an employee, click the briefcase icon on the desired employee's card. \ + Navigate to the expense list and click the supervisor comment bubble. \ + Click \"Save\" to confirm your comment.", + }, + shared: { + display: "This option allows you to choose the display mode that best suits your needs, either card view or detailed list view.", + search: "An advanced keyword search is available. Simply separate each keyword with a space, and the search bar will return results \ + that include all entered keywords.", + calendar: "The calendar speeds up navigation. It allows you to select a specific date and display the pay period that includes the selected date.", + }, + }, +}; \ No newline at end of file diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 43c82fc..faad207 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -1,235 +1,472 @@ export default { - chatbot: { - chat_header: "Agent IA", - chat_initial_message: - "Bienvenue à votre assistant technique.\nVeuillez fournir le ID du Client pour avoir un diagnostique", - chat_placeholder: "Entré un Message", - chat_thinking: "Réflexion en cours...", - }, - employee_list: { - page_header: "Répertoire du personnel", - table: { - first_name: "prénom", - last_name: "nom de famille", - email: "courriel", - phone_number: "# téléphone", - role: "rôle", - supervisor: "superviseur", - company: "Compagnie", + chatbot: { + chat_header: "Agent IA", + chat_initial_message: "Bienvenue à votre assistant technique.\nVeuillez fournir le ID du Client pour avoir un diagnostique", + chat_placeholder: "Entré un Message", + chat_thinking: "Réflexion en cours...", }, - }, - login: { - page_header: "connexion au compte", - email: "courriel", - password: "mot de passe", - button: { - connect: "connecter", - employee: "employé", - facebook: "Facebook", - remember_me: "rester connecté", + dashboard: { + carousel: { + welcome_title: "Bienvenue dans la nouvelle application Targo!", + welcome_message: "La nouvelle application est officiellement en ligne ! Plus performante et plus sécuritaire, elle conserve l’essentiel avec un design rafraîchie.", + help_title: "Nous avons une page d'aide!", + help_message: "L’application a été pensée pour être plus intuitive et moderne. En cas de doute, la page d’aide est à votre disposition.", + }, + useful_links: "liens utiles", }, - tooltip: { - coming_soon: "à venir!", - }, - }, - nav_bar: { - home: "accueil", - employee_list: "répertoire employés", - timesheet_approvals: "valider les heures", - timesheet: "carte de temps", - profile: "profil", - help: "aide", - logout: "déconnecter", - }, + help: { + label: "Centre d'aide", + tutorial: { + dashboard: { + title: "Page d'accueil", + menu: "Menu Principal", + news_feed: "Fil d'actualités", + chat_bot: "Robot conversationnel d'aide technique", + notifications: "Notifications", + }, + personal_profile: { + title: "Profil", + personal_info: "Informations personnelles", + professional_info: "Informations professionnelles", + }, + timesheets: { + title: "Carte de temps", + create_shift: "Inscrire un nouveau quart de travail", + update_shift: "Modifier un quart de travail existant", + delete_shift: "Supprimer un quart de travail de la carte de temps", + comment_shift: "Commenter un quart de travail", + create_expense: "Inscrire une dépense", + update_expense: "Modifier une dépense", + delete_expense: "Supprimer une dépense", + }, + employee_list: { + title: "Répertoire des employés ", + terminated_employees: "Employés inactifs", + }, + employee_management: { + title: "Gestion des employés ", + create_employee: "Création d'un nouvel employé", + update_employee: "Modifier les informations d'un employé", + module_access: "Outils de gestion des accès de l'application", + schedule_preset: "Gestion des horaires prédéterminés", + terminating_employee: "Rendre un employé inactif", + }, + timesheets_approval: { + title: "Validation de Carte de temps", + approval: "Validation des cartes de temps", + inspect: "Inspect timesheets", + comment_expense: "Commenter une dépense", + }, + shared: { + search: "Recherche avancée", + preferences: "Options de préférences d'affichage", + calendar: "Navigation avec l'aide du calendrier", + display: "Affichage par Cartes ou par Liste" + }, + }, + }, - profile: { - personal: { - tab_title: "personnelle", - first_name: "prénom", - last_name: "nom de famille", - phone_number: "numéro de téléphone", - address: "adresse", - address_hint: "# addresse, ville, région, pays", - birthdate: "date de naissance", + employee_list: { + page_header: "Répertoire du personnel", + table: { + first_name: "prénom", + last_name: "nom de famille", + email: "courriel", + phone_number: "# téléphone", + role: "rôle", + supervisor: "superviseur", + company: "Compagnie", + is_supervisor: "est un superviseur", + expected_daily_hours: "Heures quotidiennes attendues", + active: "actif", + inactive: "inactif", + }, + errors: { + first_name_required: "Vous devez spécifier le prénom", + last_name_required: "Vous devez spécifier le nom de famille", + company_required: "Vous devez assignerl'employé à une compagnie", + phone_number_required: "Vous devez entrer un numéro de téléphone", + hire_date_required: "Vous devez entrer une date d'embauche", + daily_hours_required: "Spécifiez le nombre d'heures quotidiennes travaillé", + no_modules_warning: "Tout les modules sont désactivés. L'utilisateur sera verrouillé hors de l'application.", + } + }, + + employee_management: { + add_employee: "Ajouter employé", + modify_employee: "Modifier employé", + access_label: "accès", + details_label: "détails", + schedule_label: "horaire", + can_be_entered_later: "FACULTATIF: peut être entré plus tard", + enter_delete_input: "tappez 'SUPPRIMER' pour confirmer", + banked_hours: "heures en banque disponibles", + sick_hours: "heures d'absence payées disponibles", + vacation_hours: "heures de vacances disponibles", + schedule_presets: { + preset_list_placeholder: "Sélectionner un horaire", + preset_name_placeholder: "nom de l'horaire", + delete_warning: "Êtes-vous certain de vouloir supprimer cet horaire?", + delete_warning_employee_1: "Cet horaire est présentement utilisé par", + delete_warning_employee_2: "La suppression n'affectera pas leurs feuilles de temps antérieures, mais ils ne pourront plus appliquer cet horaire à leurs feuilles de temps à partir de maintenant.", + }, + module_access: { + dashboard: "Accueil", + employee_list: "Répertoire du personnel", + employee_management: "Gestion employés", + personal_profile: "profil personnel", + timesheets: "carte de temps", + timesheets_approval: "validation cartes de temps", + user_access: "module access", + by_role: "par rôle", + by_module: "par module", + preset_admin: "administrateur", + preset_employee: "employé", + uncheck_all: "Tout enlever", + admin_description: "Selectionner tous les modules", + employee_description: "Selectionner seulement les modules qui sont pertinents aux employés sans accès spéciaux", + none_description: "Enlever tous les accès", + usage_description: "Vous pouvez utiliser les rôles pour sélectionner des modules prédéfinis, enlever ou ajouter des modules individuellement, ou les deux", + }, + filter: { + hide_terminated: "Cacher les employés inactifs", + sort_by_tags: "filtrer par identifiants", + }, }, - employee: { - tab_title: "carrière", - email: "courriel", - job_title: "poste", - company: "compagnie", - supervisor: "nom du superviseur", - hired_date: "date d'embauche", - }, - preferences: { - tab_title: "préférences", - display_options: "Options d'affichage", - language_options: "Options de langue", - dark_mode: "sombre", - light_mode: "clair", - }, - errors: { - must_enter_birthdate: "Vous devez entrer une date de naissance valide", - }, - }, - shared: { error: { - no_data_found: "aucune donnée à afficher", - no_search_results: "aucun résultat ne correspond à la recherche", + not_found_header: "page introuvable", + not_found_description: "Vous avez possiblement entré une mauvaise addresse URL, ou vous n'avez pas accès à cette section du site", + go_back: "retour en arrière", }, - label: { - search: "recherche", - filter: "filtres", - loading: "chargement en cours...", - language: "langue", - add: "ajouter", - save: "sauvegarder", - remove: "supprimer", - cancel: "annuler", - update: "mettre à jour", - modify: "modifier", - close: "fermer", - }, - misc: { - or: "ou", - and: "et", - to: "au", - from: "de", - yes: "oui", - no: "non", - in: "entrée", - out: "sortie", - }, - shift_type: { - regular: "régulier", - evening: "soir", - emergency: "urgence", - overtime: "supplémentaire", - holiday: "férié", - vacation: "vacances", - sick: "maladie", - remote: "télétravail", - }, - weekday: { - sunday: "dimanche", - monday: "lundi", - tuesday: "mardi", - wednesday: "mercredi", - thursday: "jeudi", - friday: "vendredi", - saturday: "samedi", - }, - }, - timesheet: { - page_header: "Carte de temps", - nav_button: { - calendar_date_picker: "Calendrier", - current_week: "Semaine actuelle", - next_week: "Prochaine semaine", - previous_week: "Semaine précédente", + login: { + page_header: "connexion au compte", + email: "courriel", + password: "mot de passe", + connected: "Connecté", + redirecting: "redirection en cours...", + button: { + connect: "connecter", + employee: "employé", + facebook: "Facebook", + remember_me: "rester connecté", + }, + tooltip: { + coming_soon: "à venir!", + }, + error: { + login_failed: "Échec à la connexion", + popups_blocked: "Les fenêtres contextuelles sont bloqués sur cet appareil", + }, }, - save_button: "Enregistrer", - cancel_button: "Annuler", - remote_button: "Télétravail", - delete_button: "Supprimer", - shift: { - actions: { - add: "Ajouter un Quart", - edit: "Modifier un Quart", - delete: "Supprimer un Quart", - delete_confirmation_msg: "Voulez-vous complètement supprimer ce quart?", - }, - types: { - label: "Type de Quart", - EMERGENCY: "Urgence", - EVENING: "Soir", - HOLIDAY: "Férié", - OVERTIME: "Supplémentaire", - REGULAR: "Régulier", - SICK: "Maladie", - VACATION: "Vacance", - REMOTE: "Télétravail", - }, - errors: { - not_found: "Aucun quart trouvé", - overlap: "Il y a un chevauchement entre deux ou plusieurs quarts", - invalid: "Entrée du quart invalide", - unknown: "Erreur inconnue", - comment_required: "un commentaire est requis", - comment_too_long: "votre commentaire est trop long", - }, - fields: { - start: "Début (HH:mm)", - end: "Fin (HH:mm)", - header_comment: "Commentaire du Quart", - textarea_comment: "Laissez votre commentaire ici", - }, - }, - expense: { - add_expense: "Ajouter une dépense", - amount: "Montant", - date: "Date", - empty_list: "Aucun dépense enregistrée", - employee_comment: "Commentaire", - supervisor_comment: "Note du Superviseur", - errors: { - date_required_or_invalid: "La date est manquante ou invalide", - comment_required: "un commentaire est requis", - comment_too_long: "votre commentaire est trop long", - amount_must_be_positive: "le montant doit être suppérieur à 0$", - mileave_must_be_positive: "le kilométrage doit être suppérieur à 0", - amount_xor_mileage: - "Vous ne pouvez pas saisir un montant et un kilométrage pour une même dépense", - mileage_required_for_type: - "Vous devez entrer une valeur en kilométrage pour ce type de dépense", - amount_required_for_type: - "Vous devez entrer une valeur en montant $ pour ce type de dépense", - }, - hints: { - amount_or_mileage: "Soit dépense ou kilométrage, pas les deux", - comment_required: "un commentaire est requis", - attach_file: "Pièce jointe", - }, - mileage: "Kilométrage", - open_btn: "Liste des Dépenses", - title: "Liste des dépenses", - total_amount: "Montant total", - total_mileage: "Kilométrage total", - type: "Type", - types: { - PER_DIEM: "Per diem", - EXPENSES: "dépense", - MILEAGE: "kilométrage", - PRIME_GARDE: "Prime de garde", - }, - }, - }, - timesheet_approvals: { - page_title: "Validation cartes de temps", - table: { - full_name: "nom complet", - email: "courriel", - expenses: "dépenses", - mileage: "kilométrage", - verified: "approuvé", - unverified: "à vérifier", + nav_bar: { + home: "accueil", + employee_list: "répertoire employés", + timesheet_approvals: "valider les heures", + timesheet: "carte de temps", + profile: "profil", + help: "aide", + logout: "déconnecter", }, - chart: { - hours_worked_title: "heures travaillées", - expenses_title: "dépenses encourues", + + profile: { + personal: { + tab_title: "personnelle", + first_name: "prénom", + last_name: "nom de famille", + phone_number: "numéro de téléphone", + address: "adresse", + address_hint: "# addresse, ville, région, pays", + birthdate: "date de naissance", + }, + employee: { + tab_title: "carrière", + email: "courriel", + job_title: "poste", + company: "compagnie", + supervisor: "nom du superviseur", + hired_date: "date d'embauche", + fired_date: "date de départ", + bankroll_id: "identifiant de paie", + }, + preferences: { + tab_title: "préférences", + display_options: "Mode d'affichage", + language_options: "Options de langue", + 'fr-FR': "Français", + 'en-CA': "English", + dark_mode: "sombre", + light_mode: "clair", + auto_mode: "automatique", + update_successful: "Préférences enregistrées", + update_failed: "Échec de sauvegarde", + }, + schedule_presets: { + tab_title: "horaire", + selected_schedule: "Horaire Sélectionné", + new_preset: "Construire un nouvel horaire", + }, + errors: { + must_enter_birthdate: "Vous devez entrer une date de naissance valide", + } }, - print_report: { - company: "compagnie", - type: "types de données", - shifts: "quarts de travail", - expenses: "dépenses", + + shared: { + error: { + no_data_found: 'aucune donnée à afficher', + no_search_results: 'aucun résultat ne correspond à la recherche', + }, + label: { + search: 'recherche', + filter: "filtres", + loading: 'chargement en cours...', + language: 'langue', + add: "ajouter", + save: "sauvegarder", + remove: "supprimer", + cancel: "annuler", + update: "mettre à jour", + modify: "modifier", + close: "fermer", + download: "télécharger", + open: "ouvrir", + }, + misc: { + or: "ou", + and: "et", + to: "au", + from: "de", + yes: "oui", + no: "non", + in: "entrée", + out: "sortie", + }, + shift_type: { + regular: "régulier", + evening: "soir", + emergency: "urgence", + overtime: "supplémentaire", + holiday: "férié", + vacation: "vacances", + sick: "maladie", + remote: "télétravail", + }, + weekday: { + sun: "dimanche", + mon: "lundi", + tue: "mardi", + wed: "mercredi", + thu: "jeudi", + fri: "vendredi", + sat: "samedi", + }, }, - tooltip: { - button_detailed_view: "vue détaillée", + + timesheet: { + page_header: "Carte de temps", + week: "semaine", + total_hours: "heures totales: ", + total_expenses: "dépenses totales: ", + vacation_available: "vacances disponibles: ", + sick_available: "congés maladie disponible: ", + current_shifts: "quarts entrées", + apply_preset: "auto-remplir", + apply_preset_day: "Appliquer horaire pour la journée", + apply_preset_week: "Appliquer horaire pour la semaine", + nav_button: { + calendar_date_picker: "Calendrier", + current_week: "Semaine actuelle", + next_week: "Prochaine période", + previous_week: "Période précédente", + }, + shift: { + actions: { + add: "Ajouter un Quart", + edit: "Modifier un Quart", + delete: "Supprimer un Quart", + delete_confirmation_msg: "Voulez-vous complètement supprimer ce quart?", + }, + types: { + label: "Type de Quart", + EMERGENCY: "Urgence", + EVENING: "Soir", + HOLIDAY: "Férié", + OVERTIME: "Supplémentaire", + REGULAR: "Régulier", + SICK: "Maladie", + VACATION: "Vacance", + REMOTE: "Télétravail", + OFFICE: "Bureau", + }, + fields: { + start: "Début (HH:mm)", + end: "Fin (HH:mm)", + header_comment: "Commentaire du Quart", + textarea_comment: "Laissez votre commentaire ici", + }, + }, + expense: { + add_expense: 'Ajouter une dépense', + amount: 'Montant', + date: 'Date', + empty_list: 'Aucun dépense enregistrée', + employee_comment: 'Commentaire', + supervisor_comment: 'Note du Superviseur', + hints: { + amount_or_mileage: "Soit dépense ou kilométrage, pas les deux", + comment_required: "un commentaire est requis", + attach_file: "Pièce jointe" + }, + mileage: "Kilométrage", + open_btn: "Liste des Dépenses", + title: "Liste des dépenses", + total_amount: "Montant total", + total_mileage: "Kilométrage total", + type: "Type", + types: { + PER_DIEM: "Per diem", + EXPENSES: "dépense", + MILEAGE: "kilométrage", + ON_CALL: "Prime de garde", + }, + }, + errors: { + INVALID_SHIFT_TIME: "Les heures d'entrée et de sortie sont inversées", + SHIFT_OVERLAP: "Il y a un chevauchement entre deux ou plusieurs quarts", + SHIFT_OVERLAP_SHORT: "Chevauchement", + INVALID_SHIFT: "Un quart de travail contient des données manquantes ou corrompues", + SHIFT_TIME_REQUIRED: "Heures manquantes", + SHIFT_TYPE_REQUIRED: "Type requis", + SHIFT_NOT_FOUND: "Quart de travail manquant ou supprimé", + PAY_PERIOD_NOT_FOUND: "Aucune période de paie ne correspond aux dates fournies", + EMPLOYEE_NOT_FOUND: "Aucun employé ne correspond aux détails de votre connexion", + INVALID_TIMESHEET: "Une feuille de temps contient des données manquantes ou corrompues", + TIMESHEET_NOT_FOUND: "Aucune feuille de temps ne correspond au détails fournis", + INVALID_EXPENSE: "Une dépense contient des données manquantes ou corrompues", + EXPENSE_NOT_FOUND: "Aucune dépense ne correspond aux détails fournis", + UPDATE_ERROR: "Une erreur est survenu lors de la mise à jour", + }, }, - }, -}; + + timesheet_approvals: { + page_title: "Validation cartes de temps", + chart: { + hours_worked_title: "heures travaillées", + expenses_title: "dépenses encourues" + }, + print_report: { + title: "options de téléchargement", + description: "Choisissez ce qui sera inclu dans le rapport", + company: "compagnies", + type: "types de données", + shifts: "quarts de travail", + expenses: "dépenses", + options: "options", + }, + table: { + full_name: "nom complet", + email: "courriel", + is_approved: "approuvé", + expenses: "dépenses", + mileage: "kilométrage", + verified: "approuvé", + unverified: "à vérifier", + inactive: "inactif", + regular: "régulier", + evening: "soir", + emergency: "urgence", + overtime: "supplémentaire", + holiday: "férié", + vacation: "vacances", + sick: "maladie", + remote: "télétravail", + weekly_hours_1: "heures semaine 1", + weekly_hours_2: "heures semaine 2", + total_hours: "heures totales", + filter_active: "montrer les employés inactifs", + filter_team: "montrer mon équipe seulement", + filter_columns: "informations affichés", + }, + tooltip: { + button_detailed_view: "vue détaillée", + approve: "mettre status approuvé", + unapprove: "enlever status approuvé", + }, + }, + + descriptions: { + dashboard: { + menu: "Pour accéder au menu principal, cliquez sur le bouton situé dans le coin supérieur gauche. Ce menu vous permet de naviguer à travers l'ensemble de l'application.", + news_feed: "Des annonces générales et des points importants y sont présentés. Cet affichage est identique pour l'ensemble des employés.", + notifications: "Les notifications sont accessibles via la clochette située dans le coin supérieur droit. Elles permettent de consulter rapidement les informations qui vous concernent, \ + par exemple : les demandes de congé, de vacances ou d'absence, les heures supplémentaires effectuées durant la semaine courante, \ + ainsi que les commentaires laissés par votre superviseur.", + chat_bot: "Pour accéder au robot, il suffit de cliquer sur la bulle « robot ». Le robot conversationnel vous permet de trouver rapidement de l'information sur un client, \ + une facture ou un appareil.", + }, + personal_profile: { + personal_info: "Dans l'onglet « Personnel », vous pouvez consulter vos informations personnelles, telles que votre nom, vos numéros de téléphone, \ + votre adresse et votre date de naissance.", + professional_info: "Dans l'onglet « Carrière », vous pouvez consulter vos informations professionnelles, comme votre poste, le nom de l'entreprise pour laquelle vous travaillez, \ + le nom et l'adresse courriel de votre superviseur, ainsi que votre date d'embauche.", + preferences: "Dans l'onglet « Préférences », vous pouvez ajuster certains paramètres selon vos préférences personnelles, tels que le mode sombre, \ + la langue et les notifications.", + }, + timesheets: { + create_shift: "Pour ajouter un quart de travail, cliquez sur l'onglet vert « Ajouter du temps » et saisissez les informations obligatoires suivantes : \ + le type de quart, l'heure de début, l'heure de fin, ainsi que le mode de travail (présentiel ou télétravail). \ + Cliquez ensuite sur « Sauvegarder », situé dans le coin supérieur droit de la carte de temps.", + update_shift: "Pour modifier un quart de travail, cliquez sur l'information à modifier, ajustez la valeur souhaitée, puis cliquez sur « Sauvegarder », \ + situé dans le coin supérieur droit de la carte de temps.", + delete_shift: "Pour supprimer un quart de travail, cliquez sur l'icône de poubelle rouge associée à l'entrée.", + comment_shift: "Pour laisser un commentaire sur un quart de travail, cliquez sur l'icône de bulle conversationnelle située à droite de l'entrée du quart de travail, \ + puis cliquez sur « Sauvegarder », dans le coin supérieur droit de la carte de temps.", + create_expense: "Pour ajouter une dépense, accédez à la liste des dépenses à l'aide du bouton situé dans le coin supérieur droit. \ + Vous devez ensuite remplir les champs suivants : la date (la date du jour est sélectionnée par défaut), le type de dépense, \ + le montant ou le kilométrage effectué, un commentaire justifiant la dépense, et joindre une pièce justificative. \ + Cliquez ensuite sur le bouton « Ajouter ».", + update_expense: "Pour modifier une dépense, accédez à la liste des dépenses, sélectionnez la dépense à modifier, apportez les changements nécessaires, \ + puis cliquez sur « Modifier » pour sauvegarder.", + delete_expense: "Pour supprimer une dépense, accédez à la liste des dépenses et cliquez sur l'icône de poubelle rouge.", + }, + employee_list: { + terminated_employees: "Cette option vous permet d'afficher ou de masquer les employés qui ne sont plus à l'emploi.", + }, + employee_management: { + create_employee: "Pour créer un employé, accédez au menu « Ajouter un employé », situé dans le coin supérieur gauche de la liste des employés. \ + Dans l'onglet « Détails », vous devez d'abord saisir l'ensemble des informations requises, à l'exception de la date de départ. \ + Ensuite, attribuez les accès nécessaires à l'employé. Optionnellement, vous pouvez lui assigner un horaire préfabriqué. \ + Cliquez sur « Sauvegarder » pour confirmer la création de l'employé.", + update_employee: "Pour mettre à jour les informations, les accès ou l'horaire d'un employé, sélectionnez son portrait et naviguez vers l'onglet approprié. \ + Apportez les modifications nécessaires, puis cliquez sur « Mettre à jour » pour confirmer.", + module_access: "Pour gérer les accès aux différentes parties de l'application, sélectionnez le portrait de l'employé désiré, puis accédez à l'onglet « Accès ». \ + Deux options sont disponibles : par rôle ou par module. Si l'employé est superviseur, le rôle « Administrateur » est suggéré. \ + Pour un employé standard, le rôle « Employé » est recommandé. Il est également possible de sélectionner des modules spécifiques dans certains cas.", + schedule_preset: "Pour attribuer, modifier ou créer un horaire pour un employé, sélectionnez d'abord l'employé, puis accédez à l'onglet « Horaire » du menu de modification. \ + Vous pouvez choisir un horaire existant, créer un nouvel horaire en lui donnant un nom unique, ou copier un horaire existant, le modifier et le renommer. \ + Une fois satisfait, cliquez sur « Mettre à jour » pour confirmer votre choix.", + terminating_employee: "Pour mettre fin à l'emploi d'un employé, sélectionnez son portrait (ou sa ligne). Une fois le menu de modification affiché, \ + entrez la date de départ et cliquez sur « Mettre à jour ».", + }, + timesheets_approval: { + approval: "Pour approuver une feuille de temps, cliquez sur le bas de la carte où se trouve l'icône de cadenas. En mode liste, \ + cliquez sur le cadenas situé à droite de la ligne correspondante.", + inspect: "Pour consulter les informations relatives aux quarts de travail ou aux dépenses d'un employé, cliquez sur l'icône de valise située dans le coin supérieur droit. \ + Vous y trouverez des statistiques sur les heures travaillées ainsi que les dépenses effectuées. Dans cette fenêtre, il est possible de modifier des quarts de travail \ + et des dépenses. Cliquez sur « Sauvegarder » pour confirmer les modifications.", + comment_expense: "Pour laisser un commentaire sur une dépense soumise par un employé, cliquez sur l'icône de valise associée à la carte de l'employé désiré. \ + Accédez à la liste des dépenses et cliquez sur la bulle de commentaire du superviseur. \ + Cliquez sur « Sauvegarder » pour confirmer votre commentaire.", + }, + shared: { + display: "Cette option permet de choisir le mode d'affichage qui vous convient le mieux, soit par carte ou sous forme de liste détaillée.", + search: "Il est possible d'effectuer une recherche avancée par mots-clés. Il suffit de séparer chaque mot par un espace, et la barre de recherche affichera \ + les résultats contenant l'ensemble des mots-clés saisis.", + calendar: "Le calendrier facilite la navigation. Il vous permet de sélectionner une date précise et d'afficher la période de paie qui inclut cette date.", + }, + }, +}; \ No newline at end of file diff --git a/src/layouts/components/main-layout-footer-bar.vue b/src/layouts/components/main-layout-footer-bar.vue index d87cd36..722af4b 100644 --- a/src/layouts/components/main-layout-footer-bar.vue +++ b/src/layouts/components/main-layout-footer-bar.vue @@ -1,10 +1,20 @@ + + diff --git a/src/layouts/components/main-layout-header-bar-notification.vue b/src/layouts/components/main-layout-header-bar-notification.vue index 89e7edf..521989d 100644 --- a/src/layouts/components/main-layout-header-bar-notification.vue +++ b/src/layouts/components/main-layout-header-bar-notification.vue @@ -1,26 +1,29 @@ - \ No newline at end of file diff --git a/src/layouts/components/main-layout-header-bar.vue b/src/layouts/components/main-layout-header-bar.vue index 9cccdbc..31d67da 100644 --- a/src/layouts/components/main-layout-header-bar.vue +++ b/src/layouts/components/main-layout-header-bar.vue @@ -1,38 +1,36 @@ - diff --git a/src/layouts/components/main-layout-left-drawer.vue b/src/layouts/components/main-layout-left-drawer.vue index b0b1fa8..498d4cf 100644 --- a/src/layouts/components/main-layout-left-drawer.vue +++ b/src/layouts/components/main-layout-left-drawer.vue @@ -1,175 +1,113 @@ - \ No newline at end of file diff --git a/src/layouts/main-layout.vue b/src/layouts/main-layout.vue index fcc21bc..240b0d3 100644 --- a/src/layouts/main-layout.vue +++ b/src/layouts/main-layout.vue @@ -1,20 +1,44 @@ - diff --git a/src/modules/auth/components/login-connection-panel.vue b/src/modules/auth/components/login-connection-panel.vue index bd5f934..0dd7755 100644 --- a/src/modules/auth/components/login-connection-panel.vue +++ b/src/modules/auth/components/login-connection-panel.vue @@ -1,21 +1,33 @@ - \ No newline at end of file diff --git a/src/modules/auth/services/services-auth.ts b/src/modules/auth/services/services-auth.ts index c0aba2f..5caaa4f 100644 --- a/src/modules/auth/services/services-auth.ts +++ b/src/modules/auth/services/services-auth.ts @@ -1,5 +1,6 @@ /* eslint-disable */ import { api } from 'src/boot/axios'; +import type { User } from 'src/modules/shared/models/user.models'; export const AuthService = { // Will likely be deprecated and relegated to Authentik @@ -7,16 +8,6 @@ export const AuthService = { //TODO: OIDC customer sign-in, eventually }, - oidcLogin: (): Window | null => { - window.addEventListener('message', (event) => { - if (event.data.type === 'authSuccess') { - //some kind of logic here to set user in store - } - }) - - return window.open('http://localhost:3000/auth/v1/login', 'authPopup', 'width=600,height=800'); - }, - logout: () => { // TODO: logout logic api.post('/auth/logout') @@ -27,8 +18,8 @@ export const AuthService = { api.post('/auth/refresh') }, - getProfile: () => { - // TODO: user info fetch logic - api.get('/auth/me') + getProfile: async (): Promise => { + const response = await api.get('/auth/me'); + return response.data; }, }; diff --git a/src/modules/dashboard/components/_shared/dashboard-container-user-card.vue b/src/modules/dashboard/components/_shared/dashboard-container-user-card.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/_shared/dashboard-container-user-menu.vue b/src/modules/dashboard/components/_shared/dashboard-container-user-menu.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/_shared/dashboard-container.vue b/src/modules/dashboard/components/_shared/dashboard-container.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/admin/admin-things.vue b/src/modules/dashboard/components/admin/admin-things.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/customer/customer-things.vue b/src/modules/dashboard/components/customer/customer-things.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/dealer/dealer-things.vue b/src/modules/dashboard/components/dealer/dealer-things.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/employee/shortcut-card.vue b/src/modules/dashboard/components/employee/shortcut-card.vue new file mode 100644 index 0000000..90ee54e --- /dev/null +++ b/src/modules/dashboard/components/employee/shortcut-card.vue @@ -0,0 +1,42 @@ + + + + + \ No newline at end of file diff --git a/src/modules/dashboard/components/main-carousel.vue b/src/modules/dashboard/components/main-carousel.vue new file mode 100644 index 0000000..5b44748 --- /dev/null +++ b/src/modules/dashboard/components/main-carousel.vue @@ -0,0 +1,72 @@ + + + \ No newline at end of file diff --git a/src/modules/dashboard/components/support/support-things.vue b/src/modules/dashboard/components/support/support-things.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/components/technician/technician-things.vue b/src/modules/dashboard/components/technician/technician-things.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/dashboard/pages/basic-dashboard.vue b/src/modules/dashboard/pages/basic-dashboard.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/employee-list/components/add-modify-dialog-access.vue b/src/modules/employee-list/components/add-modify-dialog-access.vue new file mode 100644 index 0000000..02d7017 --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-access.vue @@ -0,0 +1,194 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog-form-input.vue b/src/modules/employee-list/components/add-modify-dialog-form-input.vue new file mode 100644 index 0000000..8998149 --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-form-input.vue @@ -0,0 +1,58 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog-form-select.vue b/src/modules/employee-list/components/add-modify-dialog-form-select.vue new file mode 100644 index 0000000..9f2b9f8 --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-form-select.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog-form.vue b/src/modules/employee-list/components/add-modify-dialog-form.vue new file mode 100644 index 0000000..b992dff --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-form.vue @@ -0,0 +1,210 @@ + + + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog-schedule-preview.vue b/src/modules/employee-list/components/add-modify-dialog-schedule-preview.vue new file mode 100644 index 0000000..631909e --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-schedule-preview.vue @@ -0,0 +1,59 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog-schedule.vue b/src/modules/employee-list/components/add-modify-dialog-schedule.vue new file mode 100644 index 0000000..c8f77b2 --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog-schedule.vue @@ -0,0 +1,122 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/add-modify-dialog.vue b/src/modules/employee-list/components/add-modify-dialog.vue new file mode 100644 index 0000000..df83a8d --- /dev/null +++ b/src/modules/employee-list/components/add-modify-dialog.vue @@ -0,0 +1,119 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/customer/customer-profile.vue b/src/modules/employee-list/components/customer/customer-profile.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/employee-list/components/employee-list-table-item.vue b/src/modules/employee-list/components/employee-list-table-item.vue new file mode 100644 index 0000000..1aef68e --- /dev/null +++ b/src/modules/employee-list/components/employee-list-table-item.vue @@ -0,0 +1,107 @@ + + + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/employee-list-table.vue b/src/modules/employee-list/components/employee-list-table.vue new file mode 100644 index 0000000..6b574ce --- /dev/null +++ b/src/modules/employee-list/components/employee-list-table.vue @@ -0,0 +1,300 @@ + + + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/employee/employee-list-add-modify-dialog.vue b/src/modules/employee-list/components/employee/employee-list-add-modify-dialog.vue deleted file mode 100644 index 5c1fffe..0000000 --- a/src/modules/employee-list/components/employee/employee-list-add-modify-dialog.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/employee-list/components/schedule-presets-dialog-delete.vue b/src/modules/employee-list/components/schedule-presets-dialog-delete.vue new file mode 100644 index 0000000..23e82b7 --- /dev/null +++ b/src/modules/employee-list/components/schedule-presets-dialog-delete.vue @@ -0,0 +1,75 @@ + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/schedule-presets-dialog-row.vue b/src/modules/employee-list/components/schedule-presets-dialog-row.vue new file mode 100644 index 0000000..a9db807 --- /dev/null +++ b/src/modules/employee-list/components/schedule-presets-dialog-row.vue @@ -0,0 +1,170 @@ + + + + + \ No newline at end of file diff --git a/src/modules/employee-list/components/schedule-presets-dialog.vue b/src/modules/employee-list/components/schedule-presets-dialog.vue new file mode 100644 index 0000000..d4f1585 --- /dev/null +++ b/src/modules/employee-list/components/schedule-presets-dialog.vue @@ -0,0 +1,121 @@ + + + diff --git a/src/modules/employee-list/components/supervisor/supervisor-crew-table-item.vue b/src/modules/employee-list/components/supervisor/supervisor-crew-table-item.vue deleted file mode 100644 index cfdc610..0000000 --- a/src/modules/employee-list/components/supervisor/supervisor-crew-table-item.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/employee-list/components/supervisor/supervisor-crew-table.vue b/src/modules/employee-list/components/supervisor/supervisor-crew-table.vue deleted file mode 100644 index 495614d..0000000 --- a/src/modules/employee-list/components/supervisor/supervisor-crew-table.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/modules/employee-list/composables/use-employee-api.ts b/src/modules/employee-list/composables/use-employee-api.ts index 12ec52f..60bd474 100644 --- a/src/modules/employee-list/composables/use-employee-api.ts +++ b/src/modules/employee-list/composables/use-employee-api.ts @@ -1,18 +1,86 @@ import { useEmployeeStore } from "src/stores/employee-store"; +import { useSchedulePresetsStore } from "src/stores/schedule-presets.store"; +import { SchedulePreset } from "../models/schedule-presets.models"; +import { isShiftOverlap } from "src/modules/timesheets/utils/shift.util"; export const useEmployeeListApi = () => { - const employeeListStore = useEmployeeStore(); + const employee_store = useEmployeeStore(); + const schedule_preset_store = useSchedulePresetsStore(); - const getEmployeeList = (): Promise => { - return employeeListStore.getEmployeeList(); + const getEmployeeList = async (): Promise => { + employee_store.is_loading = true; + + const success = await employee_store.getEmployeeList(); + if (success) await schedule_preset_store.findSchedulePresetList(); + + employee_store.is_loading = false; }; - const getEmployeeDetails = (email: string): Promise => { - return employeeListStore.getEmployeeDetails(email); + const getEmployeeDetails = async (email: string): Promise => { + const success = await employee_store.getEmployeeDetails(email); + if (success && employee_store.employee.preset_id !== null) { + schedule_preset_store.setCurrentSchedulePreset(employee_store.employee.preset_id ?? -1); + } + } + + const setSchedulePreset = (preset_id: number) => { + schedule_preset_store.setCurrentSchedulePreset(preset_id); + employee_store.employee.preset_id = preset_id < 0 ? null : preset_id; + } + + const saveSchedulePreset = async () => { + // Get the currently edited schedule preset from the store (frontend model) + const preset = schedule_preset_store.current_schedule_preset; + + // Check if there's any overlap between shifts. If there is, is_error property + // will be toggled to true and save process will stop + for (const weekday of preset.weekdays) { + weekday.is_error = isShiftOverlap(weekday.shifts); + } + + if (preset.weekdays.some(weekday => weekday.is_error)) { + return; + } + + // Flatten all weekday shifts into a single array + const preset_shifts = preset.weekdays.flatMap(weekday => weekday.shifts); + + // Build a backend-compatible SchedulePreset instance + const backend_preset = new SchedulePreset( + preset.id, + preset.name, + preset_shifts + ); + + // Track whether the create/update operation succeeds + let success = false; + + // Create a new preset if it has no backend ID, otherwise update the existing one + if (preset.id === -1) + success = await schedule_preset_store.createSchedulePreset(backend_preset); + else + success = await schedule_preset_store.updateSchedulePreset(backend_preset); + + // On success, refresh the preset list and close the preset manager UI + if (success) { + await schedule_preset_store.findSchedulePresetList(); + schedule_preset_store.is_manager_open = false; + } + } + + const deleteSchedulePreset = async (preset_id: number) => { + const success = await schedule_preset_store.deleteSchedulePreset(preset_id); + if (success) { + await schedule_preset_store.findSchedulePresetList(); + schedule_preset_store.is_manager_open = false; + } } return { getEmployeeList, getEmployeeDetails, + setSchedulePreset, + saveSchedulePreset, + deleteSchedulePreset, }; }; \ No newline at end of file diff --git a/src/modules/employee-list/employee-constants.ts b/src/modules/employee-list/employee-constants.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/employee-list/employee-list-utils.ts b/src/modules/employee-list/employee-list-utils.ts new file mode 100644 index 0000000..5b5b6ba --- /dev/null +++ b/src/modules/employee-list/employee-list-utils.ts @@ -0,0 +1,17 @@ +import type { EmbeddedValidationRule, EmbeddedValidationRuleFn } from "quasar"; + +export type QuasarRules = Record; +type EmployeeProfileValidationRule = EmbeddedValidationRule | ((value: T, rules: QuasarRules, error_message: string) => boolean | string | Promise); + +export const useEmployeeProfileRules = () => { + const isNotEmpty: EmployeeProfileValidationRule = (value, _rules, error_message) => (value !== undefined && value !== null && value !== '') || error_message; + + return { + isNotEmpty, + } +} + +export const company_options = [ + { label: 'Targo', value: 'Targo' }, + { label: 'Solucom', value: 'Solucom' }, +] \ No newline at end of file diff --git a/src/modules/employee-list/models/employee-profile.models.ts b/src/modules/employee-list/models/employee-profile.models.ts new file mode 100644 index 0000000..72660fc --- /dev/null +++ b/src/modules/employee-list/models/employee-profile.models.ts @@ -0,0 +1,149 @@ +import type { QSelectOption, QTableColumn } from "quasar"; +import type { UserModuleAccess } from "src/modules/shared/models/user.models"; + +export type ModuleAccessPreset = 'admin' | 'supervisor' | 'employee' | 'none'; +export type CompanyNames = 'Targo' | 'Solucom'; + +export interface PaidTimeOff { + sick_hours: number; + vacation_hours: number; + banked_hours: number; + last_updated?: string | null; +} + +export class EmployeeProfile { + first_name: string; + last_name: string; + supervisor_full_name: string; + company_name: CompanyNames; + job_title: string; + email: string; + phone_number: string; + first_work_day: string; + last_work_day?: string | null; + external_payroll_id?: number; + daily_expected_hours?: number; + paid_time_off?: PaidTimeOff; + residence: string; + birth_date: string; + is_supervisor: boolean; + user_module_access: UserModuleAccess[]; + preset_id?: number | null; + + constructor() { + this.first_name = ''; + this.last_name = ''; + this.supervisor_full_name = ''; + this.company_name = 'Targo'; + this.job_title = ''; + this.email = ''; + this.phone_number = ''; + this.first_work_day = ''; + this.last_work_day = null; + this.residence = ''; + this.birth_date = ''; + this.is_supervisor = false; + this.user_module_access = ['dashboard',]; + } +} + +export interface EmployeeListFilters { + search_bar_string: string; + hide_inactive_users: boolean; +}; + +export const employee_list_columns: QTableColumn[] = [ + { + name: 'first_name', + label: 'timesheet_approvals.table.full_name', + field: 'first_name', + align: 'left', + sortable: true, + }, + { + name: 'last_name', + label: 'employee_list.table.last_name', + field: 'last_name', + align: 'left', + sortable: true, + }, + { + name: 'email', + label: 'employee_list.table.email', + field: 'email', + align: 'left', + sortable: true, + }, + { + name: 'supervisor_full_name', + label: 'employee_list.table.supervisor', + field: 'supervisor_full_name', + align: 'left', + sortable: true, + }, + { + name: 'company_name', + label: 'employee_list.table.company', + field: 'company_name', + align: 'left', + sortable: true, + }, + { + name: 'phone_number', + label: 'employee_list.table.phone_number', + field: 'phone_number', + align: 'left', + sortable: true, + }, + { + name: 'job_title', + label: 'employee_list.table.role', + field: 'job_title', + align: 'left', + }, + { + name: 'expected_daily_hours', + label: 'employee_list.table.expected_daily_hours', + field: 'daily_expected_hours', + align: 'left', + }, + { + name: 'last_work_day', + label: 'status', + field: 'last_work_day', + align: 'center', + sortable: true, + sort: (a: string | null, b: string | null) => { + if (a === null && b === null) return 0; + else if (a === null && b !== null) return 1; + else return -1; + }, + }, +]; + +export const employee_access_options: QSelectOption[] = [ + { label: 'dashboard', value: 'dashboard' }, + { label: 'employee_list', value: 'employee_list' }, + { label: 'personal_profile', value: 'personal_profile' }, + { label: 'timesheets', value: 'timesheets' }, + { label: 'employee_management', value: 'employee_management' }, + { label: 'timesheets_approval', value: 'timesheets_approval' }, +] + +export const employee_access_presets: Record = { + 'admin' : ['dashboard', 'employee_list', 'employee_management', 'personal_profile', 'timesheets', 'timesheets_approval'], + 'supervisor' : ['dashboard', 'employee_list', 'personal_profile', 'timesheets', 'timesheets_approval'], + 'employee' : ['dashboard', 'timesheets', 'personal_profile', 'employee_list'], + 'none' : [], +} + +export const getEmployeeAccessOptionIcon = (module: UserModuleAccess): string => { + switch (module) { + case 'dashboard': return 'home'; + case 'employee_list' : return 'groups'; + case 'employee_management': return 'las la-user-edit'; + case 'personal_profile': return 'las la-id-card'; + case 'timesheets': return 'punch_clock'; + case 'timesheets_approval': return 'event_available'; + } +} \ No newline at end of file diff --git a/src/modules/employee-list/models/schedule-presets.models.ts b/src/modules/employee-list/models/schedule-presets.models.ts new file mode 100644 index 0000000..1f3c85a --- /dev/null +++ b/src/modules/employee-list/models/schedule-presets.models.ts @@ -0,0 +1,59 @@ +import type { ShiftType } from "src/modules/timesheets/models/shift.models"; + +export type Weekday = 'SUN' | 'MON' | 'TUE' | 'WED' | 'THU' | 'FRI' | 'SAT'; + +export const WEEKDAYS: Weekday[] = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']; + +export type PresetManagerMode = 'create' | 'update' | 'copy' | 'delete'; + +export class SchedulePreset { + id: number; + name: string; + shifts: SchedulePresetShift[]; + + constructor(id?: number, name?: string, shifts?: SchedulePresetShift[]) { + this.id = id ?? -1; + this.name = name ?? 'default'; + this.shifts = shifts ?? []; + } +} + +export class SchedulePresetShift { + preset_id: number; + week_day: Weekday; + type: ShiftType; + start_time: string; + end_time: string; + is_remote: boolean; + + constructor(weekday: Weekday) { + this.preset_id = -1; + this.week_day = weekday; + this.type = 'REGULAR'; + this.start_time = '00:00'; + this.end_time = '00:00'; + this.is_remote = false; + } +} + +export class SchedulePresetFrontend { + id: number; + name: string; + weekdays: WeekdayPresetShifts[]; + + constructor(schedule_preset?: SchedulePreset) { + this.id = schedule_preset?.id ?? -1; + this.name = schedule_preset?.name ?? ''; + this.weekdays = WEEKDAYS.map(day => ({ + day, + is_error: false, + shifts: schedule_preset !== undefined ? schedule_preset?.shifts.filter(shift => shift.week_day === day) : [], + })) + } +} + +export interface WeekdayPresetShifts { + day: Weekday; + is_error: boolean; + shifts: SchedulePresetShift[]; +} \ No newline at end of file diff --git a/src/modules/employee-list/pages/supervisor-crew-add-employee-page.vue b/src/modules/employee-list/pages/supervisor-crew-add-employee-page.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/modules/employee-list/services/employee-list-service.ts b/src/modules/employee-list/services/employee-list-service.ts new file mode 100644 index 0000000..d2c0c7d --- /dev/null +++ b/src/modules/employee-list/services/employee-list-service.ts @@ -0,0 +1,31 @@ +import { api } from 'src/boot/axios'; +import type { EmployeeProfile } from 'src/modules/employee-list/models/employee-profile.models'; +import type { BackendResponse } from 'src/modules/shared/models/backend-response.models'; + +export const EmployeeListService = { + getEmployeeList: async (): Promise> => { + const response = await api.get>('/employees/employee-list') + return response.data; + + }, + + getEmployeeDetails: async (): Promise> => { + const response = await api.get('employees/profile'); + return response.data; + }, + + getEmployeeDetailsWithEmployeeEmail: async (employee_email: string): Promise> => { + const response = await api.get(`employees/profile?employee_email=${employee_email}`); + return response.data; + }, + + createNewEmployee: async (profile: Omit): Promise> => { + const response = await api.post('employees/create', profile); + return response.data; + }, + + updateEmployee: async (profile: EmployeeProfile): Promise> => { + const response = await api.patch('employees/update', profile); + return response.data; + }, +}; \ No newline at end of file diff --git a/src/modules/employee-list/services/schedule-presets-service.ts b/src/modules/employee-list/services/schedule-presets-service.ts new file mode 100644 index 0000000..b288363 --- /dev/null +++ b/src/modules/employee-list/services/schedule-presets-service.ts @@ -0,0 +1,30 @@ +import { api } from "src/boot/axios"; +import type { SchedulePreset } from "src/modules/employee-list/models/schedule-presets.models"; +import type { BackendResponse } from "src/modules/shared/models/backend-response.models"; + +export const SchedulePresetsService = { + createSchedulePresets: async (preset: SchedulePreset) => { + const response = await api.post(`/schedule-presets/create/`, preset); + return response.data; + }, + + updateSchedulePresets: async (preset: SchedulePreset): Promise> => { + const response = await api.patch(`/schedule-presets/update`, preset); + return response.data; + }, + + deleteSchedulePresets: async (preset_id: number): Promise> => { + const response = await api.delete(`/schedule-presets/delete/${preset_id}`); + return response.data; + }, + + getSchedulePresetsList: async (): Promise> => { + const response = await api.get(`/schedule-presets/find-list`); + return response.data; + }, + + applyPresets: async (preset_name: string, start_date: string) => { + const response = await api.post(`/schedule-presets/apply-presets/`, { preset: preset_name, start: start_date }); + return response.data; + }, +}; \ No newline at end of file diff --git a/src/modules/employee-list/services/services-employee-list.ts b/src/modules/employee-list/services/services-employee-list.ts deleted file mode 100644 index cc36b98..0000000 --- a/src/modules/employee-list/services/services-employee-list.ts +++ /dev/null @@ -1,17 +0,0 @@ -// /* eslint-disable */ -import { api } from 'src/boot/axios'; -import type { EmployeeListTableItem } from '../types/employee-list-table-interface'; -import type { EmployeeProfile } from '../types/employee-profile-interface'; - - -export const EmployeeListService = { - getEmployeeList: async (): Promise => { - const response = await api.get('/employees/employee-list') - return response.data; - }, - - getEmployeeDetails: async (email: string): Promise => { - const response = await api.get('employees/profile/' + email); - return response.data; - }, -}; \ No newline at end of file diff --git a/src/modules/employee-list/types/employee-list-table-interface.ts b/src/modules/employee-list/types/employee-list-table-interface.ts deleted file mode 100644 index 43feb85..0000000 --- a/src/modules/employee-list/types/employee-list-table-interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface EmployeeListTableItem { - first_name: string; - last_name: string; - email: string; - supervisor_full_name: string | null; - company_name: number; - job_title: string; -}; \ No newline at end of file diff --git a/src/modules/employee-list/types/employee-profile-interface.ts b/src/modules/employee-list/types/employee-profile-interface.ts deleted file mode 100644 index 9f8cae0..0000000 --- a/src/modules/employee-list/types/employee-profile-interface.ts +++ /dev/null @@ -1,27 +0,0 @@ -export interface EmployeeProfile { - first_name: string; - last_name: string; - supervisor_full_name: string; - company_name: number; - job_title: string; - email: string; - phone_number: string; - first_work_day: string; - last_work_day: string; - residence: string; - birth_date: string; -} - -export const default_employee_profile: EmployeeProfile = { - first_name: '', - last_name: '', - supervisor_full_name: '', - company_name: -1, - job_title: '', - email: '', - phone_number: '', - first_work_day: '', - last_work_day: '', - residence: '', - birth_date: '', -} \ No newline at end of file diff --git a/src/modules/help/components/help-module.vue b/src/modules/help/components/help-module.vue new file mode 100644 index 0000000..f947c35 --- /dev/null +++ b/src/modules/help/components/help-module.vue @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/src/modules/help/models/help-module.model.ts b/src/modules/help/models/help-module.model.ts new file mode 100644 index 0000000..261fc5e --- /dev/null +++ b/src/modules/help/models/help-module.model.ts @@ -0,0 +1,152 @@ +import type { UserModuleAccess } from 'src/modules/shared/models/user.models'; + +export type HelpModuleOptions = { + label: string; + path: string; + description: string; + icon: string; +}; + +export type Options = Record; +export type PartialOptions = Partial>; + + + +//Shared images and descriptions +import calendar from 'src/assets/help-ss/calendar.png'; +import employee_list_display from 'src/assets/help-ss/employee-list-grid.png'; +import employee_list_card from 'src/assets/help-ss/employee-list.png'; +import search_bar from 'src/assets/help-ss/search-bar.png'; + +const calendar_nav_desc = "descriptions.shared.calendar"; +const display_desc = "descriptions.shared.display"; +const search_bar_desc = "descriptions.shared.search"; + +// Dashboard images and descriptions +import dashboard from 'src/assets/help-ss/dashboard.png'; +import menu from 'src/assets/help-ss/dashboard.png'; +import notifications from 'src/assets/help-ss/dashboard.png'; +import chatbot from 'src/assets/help-ss/dashboard.png'; + +const menu_desc = "descriptions.dashboard.menu"; +const news_feed_desc = "descriptions.dashboard.news_feed"; +const chat_bot_desc = "descriptions.dashboard.chat_bot"; +const notification_desc = "descriptions.dashboard.notifications"; + +export const dashboard_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.dashboard.menu', path: dashboard, description: menu_desc, icon: 'menu' }, + { label: 'help.tutorial.dashboard.news_feed', path: menu, description: news_feed_desc, icon: 'newspaper' }, + { label: 'help.tutorial.dashboard.notifications', path: notifications, description: notification_desc, icon: 'notifications_active' }, + { label: 'help.tutorial.dashboard.chat_bot', path: chatbot, description: chat_bot_desc, icon: 'smart_toy' }, +]; + +// profile images and descriptions +import personal_info from 'src/assets/help-ss/personal_infos.png'; +import professionnal_info from 'src/assets/help-ss/professionnal_infos.png'; +import preferences from 'src/assets/help-ss/preferences.png'; + +const personal_infos_desc = "descriptions.personal_profile.personal_info"; +const professional_info_desc = "descriptions.personal_profile.professional_info"; +const preferences_details_desc = "descriptions.personal_profile.preferences"; + +export const profile_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.personal_profile.personal_info', path: personal_info, description: personal_infos_desc, icon: 'contact_page' }, + { label: 'help.tutorial.personal_profile.professional_info', path: professionnal_info, description: professional_info_desc, icon: 'badge' }, + { label: 'help.tutorial.shared.preferences', path: preferences, description: preferences_details_desc, icon: 'display_settings' }, +]; + +// timesheet images and descriptions +import create_shift from 'src/assets/help-ss/create-shift.png'; +import update_shift from 'src/assets/help-ss/update-shift.png'; +import delete_shift from 'src/assets/help-ss/delete-shift.png'; +import comment_shift from 'src/assets/help-ss/commenting-shift.png'; +import create_expense from 'src/assets/help-ss/expenses.png'; +import delete_expense from 'src/assets/help-ss/delete-expense.png'; +import update_expense from 'src/assets/help-ss/update-expense.png'; + +const create_shift_desc = "descriptions.timesheets.create_shift"; +const update_shift_desc = "descriptions.timesheets.update_shift"; +const delete_shift_desc = "descriptions.timesheets.delete_shift"; +const comment_shift_desc = "descriptions.timesheets.comment_shift"; +const create_expense_desc = "descriptions.timesheets.create_expense"; +const update_expense_desc = "descriptions.timesheets.update_expense"; +const delete_expense_desc = "descriptions.timesheets.delete_expense"; + +export const timesheets_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.timesheets.create_shift', path: create_shift, description: create_shift_desc, icon: 'add' }, + { label: 'help.tutorial.timesheets.update_shift', path: update_shift, description: update_shift_desc, icon: 'create' }, + { label: 'help.tutorial.timesheets.delete_shift', path: delete_shift, description: delete_shift_desc, icon: 'las la-trash' }, + { label: 'help.tutorial.timesheets.comment_shift', path: comment_shift, description: comment_shift_desc, icon: 'chat_bubble_outline' }, + { label: 'help.tutorial.timesheets.create_expense', path: create_expense, description: create_expense_desc, icon: 'add' }, + { label: 'help.tutorial.timesheets.update_expense', path: update_expense, description: update_expense_desc, icon: 'create' }, + { label: 'help.tutorial.timesheets.delete_expense', path: delete_expense, description: delete_expense_desc, icon: 'clear' }, + { label: 'help.tutorial.shared.calendar', path: calendar, description: calendar_nav_desc, icon: 'calendar_month' }, +]; + +// employee management images and descriptions +import terminated_employee_display from 'src/assets/help-ss/terminated-employee-list.png'; +import create_employee from 'src/assets/help-ss/create-employee.png'; +import update_employee from 'src/assets/help-ss/update-employee.png'; +import access_management from 'src/assets/help-ss/access-management.png'; +import schedule_preset from 'src/assets/help-ss/schedule-preset-management.png'; + +const terminated_employee_desc = "descriptions.employee_list.terminated_employees"; +const terminating_employee_desc = "descriptions.employee_management.terminating_employee"; +const create_employee_desc = "descriptions.employee_management.create_employee"; +const update_employee_desc = "descriptions.employee_management.update_employee"; +const module_access_desc = "descriptions.employee_management.module_access"; +const schedule_preset_desc = "descriptions.employee_management.schedule_preset"; + + +export const employee_list_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.shared.display', path: employee_list_card, description: display_desc, icon: 'display_settings' }, + { label: 'help.tutorial.shared.search', path: search_bar, description: search_bar_desc, icon: 'search' }, +]; + +export const employee_management_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.employee_list.terminated_employees', path: terminated_employee_display, description: terminated_employee_desc, icon: 'work_off' }, + { label: 'help.tutorial.employee_management.create_employee', path: create_employee, description: create_employee_desc, icon: 'person_add' }, + { label: 'help.tutorial.employee_management.update_employee', path: update_employee, description: update_employee_desc, icon: 'las la-id-card' }, + { label: 'help.tutorial.employee_management.module_access', path: access_management, description: module_access_desc, icon: 'las la-key' }, + { label: 'help.tutorial.employee_management.schedule_preset', path: schedule_preset, description: schedule_preset_desc, icon: 'calendar_month' }, + { label: 'help.tutorial.employee_management.terminating_employee', path: update_employee, description: terminating_employee_desc, icon: 'work_off' }, + { label: 'help.tutorial.shared.display', path: employee_list_display, description: display_desc, icon: 'display_settings' }, + { label: 'help.tutorial.shared.search', path: search_bar, description: search_bar_desc, icon: 'search' }, +]; + +// Timesheets approval images and descriptions +import comment_expense from 'src/assets/help-ss/timesheet-details.png'; +import timesheet_approval_inspect from 'src/assets/help-ss/timesheet-approvals.png'; +import timesheet_details from 'src/assets/help-ss/timesheet-details.png'; +import timesheet_approval_list from 'src/assets/help-ss/timesheet-appovals-list.png'; + + +const comment_expense_desc = "descriptions.timesheets_approval.comment_expense"; +const timesheets_approval_desc = "descriptions.timesheets_approval.approval"; +const timesheets_approval_inspect_desc = "descriptions.timesheets_approval.inspect"; + +export const timesheets_approval_options: HelpModuleOptions[] = [ + { label: 'help.tutorial.timesheets_approval.approval', path: timesheet_approval_inspect, description: timesheets_approval_desc, icon: 'verified' }, + { label: 'help.tutorial.timesheets_approval.inspect', path: timesheet_details, description: timesheets_approval_inspect_desc, icon: 'work_history' }, + { label: 'help.tutorial.timesheets_approval.comment_expense', path: comment_expense, description: comment_expense_desc, icon: 'chat_bubble_outline' }, + { label: 'help.tutorial.shared.display', path: timesheet_approval_list, description: display_desc, icon: 'display_settings' }, + { label: 'help.tutorial.shared.search', path: search_bar, description: search_bar_desc, icon: 'search' }, + { label: 'help.tutorial.shared.calendar', path: calendar, description: calendar_nav_desc, icon: 'calendar_month' }, +]; + + + + +export const help_module_details: Options = { + dashboard: [], + personal_profile: profile_options, + timesheets: timesheets_options, + employee_list: employee_list_options, + employee_management: employee_management_options, + timesheets_approval: timesheets_approval_options, +}; + + + + + diff --git a/src/modules/help/services/help.service.ts b/src/modules/help/services/help.service.ts new file mode 100644 index 0000000..ccd8ba2 --- /dev/null +++ b/src/modules/help/services/help.service.ts @@ -0,0 +1,10 @@ +import { api } from "src/boot/axios"; +import type { BackendResponse } from "src/modules/shared/models/backend-response.models"; +import type { UserModuleAccess } from "src/modules/shared/models/user.models"; + +export const HelpService = { + getHelpModules: async (): Promise> => { + const response = await api.get>(`/help`); + return response.data; + } +} \ No newline at end of file diff --git a/src/modules/profile/components/employee/menu-employee.vue b/src/modules/profile/components/employee/menu-employee.vue new file mode 100644 index 0000000..7d666ba --- /dev/null +++ b/src/modules/profile/components/employee/menu-employee.vue @@ -0,0 +1,78 @@ + + + + \ No newline at end of file diff --git a/src/modules/profile/components/employee/menu-panel-employee.vue b/src/modules/profile/components/employee/menu-panel-employee.vue new file mode 100644 index 0000000..cf6649a --- /dev/null +++ b/src/modules/profile/components/employee/menu-panel-employee.vue @@ -0,0 +1,66 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/employee/menu-panel-personal.vue b/src/modules/profile/components/employee/menu-panel-personal.vue new file mode 100644 index 0000000..4264348 --- /dev/null +++ b/src/modules/profile/components/employee/menu-panel-personal.vue @@ -0,0 +1,68 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/employee/profile-panel-info-employee.vue b/src/modules/profile/components/employee/profile-panel-info-employee.vue deleted file mode 100644 index c5badb0..0000000 --- a/src/modules/profile/components/employee/profile-panel-info-employee.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/employee/profile-panel-info-personal.vue b/src/modules/profile/components/employee/profile-panel-info-personal.vue deleted file mode 100644 index 3167479..0000000 --- a/src/modules/profile/components/employee/profile-panel-info-personal.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/shared/menu-header.vue b/src/modules/profile/components/shared/menu-header.vue new file mode 100644 index 0000000..39ae2fa --- /dev/null +++ b/src/modules/profile/components/shared/menu-header.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/shared/menu-panel-input-field.vue b/src/modules/profile/components/shared/menu-panel-input-field.vue new file mode 100644 index 0000000..f17ae24 --- /dev/null +++ b/src/modules/profile/components/shared/menu-panel-input-field.vue @@ -0,0 +1,47 @@ + + + + + \ No newline at end of file diff --git a/src/modules/profile/components/shared/menu-panel-preferences.vue b/src/modules/profile/components/shared/menu-panel-preferences.vue new file mode 100644 index 0000000..135678c --- /dev/null +++ b/src/modules/profile/components/shared/menu-panel-preferences.vue @@ -0,0 +1,75 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/shared/menu-panel-schedule-presets.vue b/src/modules/profile/components/shared/menu-panel-schedule-presets.vue new file mode 100644 index 0000000..3f2d9cd --- /dev/null +++ b/src/modules/profile/components/shared/menu-panel-schedule-presets.vue @@ -0,0 +1,45 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/shared/menu-template.vue b/src/modules/profile/components/shared/menu-template.vue new file mode 100644 index 0000000..6f3a1ad --- /dev/null +++ b/src/modules/profile/components/shared/menu-template.vue @@ -0,0 +1,61 @@ + + + \ No newline at end of file diff --git a/src/modules/profile/components/shared/profile-header.vue b/src/modules/profile/components/shared/profile-header.vue deleted file mode 100644 index b63319e..0000000 --- a/src/modules/profile/components/shared/profile-header.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/shared/profile-panel-input-field.vue b/src/modules/profile/components/shared/profile-panel-input-field.vue deleted file mode 100644 index b69e4d6..0000000 --- a/src/modules/profile/components/shared/profile-panel-input-field.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/shared/profile-panel-preferences.vue b/src/modules/profile/components/shared/profile-panel-preferences.vue deleted file mode 100644 index 769879f..0000000 --- a/src/modules/profile/components/shared/profile-panel-preferences.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/shared/profile-panel-select-field.vue b/src/modules/profile/components/shared/profile-panel-select-field.vue deleted file mode 100644 index d4f98e7..0000000 --- a/src/modules/profile/components/shared/profile-panel-select-field.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/components/shared/profile-tab-menu-template.vue b/src/modules/profile/components/shared/profile-tab-menu-template.vue deleted file mode 100644 index af02408..0000000 --- a/src/modules/profile/components/shared/profile-tab-menu-template.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - \ No newline at end of file diff --git a/src/modules/profile/models/preferences.models.ts b/src/modules/profile/models/preferences.models.ts new file mode 100644 index 0000000..c9e0a82 --- /dev/null +++ b/src/modules/profile/models/preferences.models.ts @@ -0,0 +1,33 @@ +import type { MessageLanguages } from "src/boot/i18n"; + +export interface DarkModeOption { + label: string; + value: boolean | null; + quasar_value: boolean | "auto"; + icon: string; +} +export const dark_mode_options: DarkModeOption[] = [ + { label: 'profile.preferences.dark_mode', value: true, quasar_value: true, icon: 'dark_mode'}, + { label: 'profile.preferences.light_mode', value: false, quasar_value: false, icon: 'light_mode'}, + { label: 'profile.preferences.auto_mode', value: null, quasar_value: "auto", icon: 'brightness_auto'}, +] + +export class Preferences { + id: number; + notifications: boolean; + is_dark_mode: boolean | null; + display_language: MessageLanguages; + is_lefty_mode: boolean; + is_employee_list_grid: boolean; + is_timesheet_approval_grid: boolean; + + constructor() { + this.id = -1; + this.notifications = true; + this.is_dark_mode = null; + this.display_language = 'fr-FR'; + this.is_lefty_mode = false; + this.is_employee_list_grid = true; + this.is_timesheet_approval_grid = true; + } +} \ No newline at end of file diff --git a/src/modules/profile/pages/employee/profile-employee.vue b/src/modules/profile/pages/employee/profile-employee.vue deleted file mode 100644 index 775e750..0000000 --- a/src/modules/profile/pages/employee/profile-employee.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/modules/profile/services/profile-service.ts b/src/modules/profile/services/profile-service.ts new file mode 100644 index 0000000..3757e17 --- /dev/null +++ b/src/modules/profile/services/profile-service.ts @@ -0,0 +1,15 @@ +import { api } from "src/boot/axios"; +import type { Preferences } from "src/modules/profile/models/preferences.models"; +import type { BackendResponse } from "src/modules/shared/models/backend-response.models"; + +export const ProfileService = { + getUserPreferences: async (): Promise> => { + const response = await api.get>(`/preferences`); + return response.data; + }, + + updateUserPreferences: async (new_preferences: Preferences): Promise> => { + const response = await api.patch>(`/preferences/update`, new_preferences); + return response.data; + }, +}; \ No newline at end of file diff --git a/src/modules/shared/components/horizontal-slide-transition.vue b/src/modules/shared/components/horizontal-slide-transition.vue new file mode 100644 index 0000000..425020a --- /dev/null +++ b/src/modules/shared/components/horizontal-slide-transition.vue @@ -0,0 +1,78 @@ + + + + + + + diff --git a/src/modules/shared/components/language-switch.vue b/src/modules/shared/components/language-switch.vue index 5284226..e2ca11c 100644 --- a/src/modules/shared/components/language-switch.vue +++ b/src/modules/shared/components/language-switch.vue @@ -1,36 +1,50 @@ - \ No newline at end of file diff --git a/src/modules/shared/components/loading-overlay.vue b/src/modules/shared/components/loading-overlay.vue new file mode 100644 index 0000000..f3bd6d7 --- /dev/null +++ b/src/modules/shared/components/loading-overlay.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/src/modules/shared/components/page-header-template.vue b/src/modules/shared/components/page-header-template.vue index 24106a7..15a71ba 100644 --- a/src/modules/shared/components/page-header-template.vue +++ b/src/modules/shared/components/page-header-template.vue @@ -1,30 +1,71 @@ - \ No newline at end of file diff --git a/src/modules/shared/components/pay-period-navigator.vue b/src/modules/shared/components/pay-period-navigator.vue index 4485c1e..de20dfc 100644 --- a/src/modules/shared/components/pay-period-navigator.vue +++ b/src/modules/shared/components/pay-period-navigator.vue @@ -1,22 +1,30 @@ - \ No newline at end of file diff --git a/src/modules/shared/components/q-table-filters.vue b/src/modules/shared/components/q-table-filters.vue index 1cb919a..727a87c 100644 --- a/src/modules/shared/components/q-table-filters.vue +++ b/src/modules/shared/components/q-table-filters.vue @@ -1,34 +1,24 @@