diff --git a/web/src/pages/Settings/Settings.jsx b/web/src/pages/Settings/Settings.jsx index 487368a..ce8c8c2 100644 --- a/web/src/pages/Settings/Settings.jsx +++ b/web/src/pages/Settings/Settings.jsx @@ -1,501 +1,496 @@ -import React, { useEffect, useRef, useState } from 'react'; -import styled from '@emotion/styled'; -import { Stack } from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import EditOffIcon from '@mui/icons-material/EditOff'; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import { ToggleTabs, TransferBox, useLocalStore } from '@components'; -import { settingsFields } from './helpers'; - -const OuterContainer = styled(Stack)` - position: relative; - display: flex; - align-items: center; - flex-direction: row; - justify-content: center; - padding: 10px 10px 0px 0px; -`; - -const Border = styled('div')` - height: 1px; - width: 100%; - background-color: #A8A8A8; -`; - -const Tab = styled('div')` - position: relative; - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-end; - height: 100%; - padding: 6px 16px; - font-size: 20px; - font-weight: 800; - color: grey; - background: none; - border: none; - cursor: pointer; - font-family: "WDXL Lubrifont TC"; - letter-spacing: .05em; - word-spacing: .2em; -`; - -const SlidingIndicator = styled('div')` - position: absolute; - height: 1px; - bottom: -1px; - background-color: #4D79FF; - transition: left 0.3s ease, width 0.3s ease; -`; - -const CardShell = styled('div')` - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 10px; -`; - -const Card = styled('div')` - background-color: #C7C7C7; - width: 50%; - min-width: 750px; - padding: 20px; - border-radius: 10px; - margin: 5px; -`; - -const CardTitle = styled('p')` - color: white; - font-weight: 400; - font-size: 20px; - font-family: "WDXL Lubrifont TC"; - padding-bottom: 5px; -`; - -const CardHeader = styled('div')` - display: flex; - justify-content: space-between; - flex-direction: row; - padding: 10px; -`; - -const EditArea = styled('div')` - display: flex; - flex-direction: row; - justify-content: flex-end; - padding-top: 10px; - color: #4D79FF; - font-weight: 600; -`; - -const EditTextButton = styled('div')` - display: flex; - flex-direction: row; - align-items: center; - cursor: pointer; - gap: 4px; - padding-bottom: 2px; - border-bottom: 2px solid transparent; - transition: border-bottom 0.2s ease; - - &:hover { - border-bottom: 2px solid #4D79FF; - } -`; - -const CardBody = styled('div')` - display: flex; - flex-direction: column; - align-items: center; -`; - -const InnerCard = styled('div')` - display: flex; - flex-direction: column; - padding: 10px; - width: 50%; - - ${({ centered }) => centered && ` - align-items: center; - `} -`; - -const InnerCardRow = styled('div')` - display: flex; - flex-direction: row; - padding: 5px; -`; - -const InnerCardRowLabel = styled('label')` - display: flex; - justify-content: flex-end; - text-align: right; - width: 60%; - padding-right: 10px; - font-size: 14px; - align-items: center; -`; - -const InnerCardRowInput = styled('input')` - display: flex; - justify-content: flex-end; - width: 100%; - padding: 4px; -`; - -const InnerCardRadioInput = styled('input')` - padding-right: 5px; -`; - -const InnerCardRadioLabel = styled('label')` - font-size: 14px; - padding-left: 5px; - align-items: center; -`; - -const InnerCardRowRadioDiv = styled('div')` - display: flex; - justify-content: space-evenly; - width: 100%; - padding: 4px; -`; - -const FormRadioButtonLabel = styled('label')``; - -const FormInputButtonDiv = styled('div')` - display: flex; - flex-direction: row; - justify-content: flex-end; - padding-top: 10px; -`; - -const FormInputButton = styled('input')` - padding: 4px 10px; - border-radius: 4px; -`; - -export const Settings = () => { - const { user, department, setDepartment } = useLocalStore(); - - const isAdministrator = user?.administrator; - const isManager = user?.manager; - const isScheduler = user?.scheduler; - - const originalDepartmentRef = useRef(department); - const [formValues, setFormValues] = useState(() => { - const initial = {}; - settingsFields.forEach(section => { - section.cards.forEach(card => { - card.fields.forEach(field => { - initial[field.id] = department?.[field.id] || ''; - }); - }); - }); - return initial; - }); - const pageRefs = useRef({}); - const tabs = [ - { - label: 'Personal', - value: 'personal' - }, - { - label: 'Department', - value: 'department' - } - ]; - - const [windowWidth, setWindowWidth] = useState(window.innerWidth); - const [editMode, setEditMode] = useState(null); - const [tabValue, setTabValue] = useState(tabs[0]); - const [pageValue, setPageValue] = useState({}); - const [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0 }); - - const getChangedFields = (original, current) => { - const changed = {}; - for (const key in current) { - if (current[key] !== original[key]) { - changed[key] = current[key]; - } - } - return changed; - }; - - const changedFields = getChangedFields(originalDepartmentRef.current, formValues); - const hasChanges = Object.keys(changedFields).length > 0; - - const onSubmit = (data) => { - console.log('data: ', data); - setDepartment({ - ...department, - ...data - }); - originalDepartmentRef.current = { - ...originalDepartmentRef.current, - ...data - }; - setEditMode(null); - }; - - const formatPhoneNumber = (value) => { - const cleaned = value.replace(/\D/g, '').slice(0, 10); // Only digits, max 10 - const length = cleaned.length; - - if (length === 0) return ''; - if (length < 4) return `(${cleaned}`; - if (length < 7) return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3)}`; - return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`; - }; - - - const handleChange = (e, type) => { - let { name, value } = e.target; - if (type === 'phone') { - value = formatPhoneNumber(value); - } - setFormValues(prev => ({ ...prev, [name]: value })); - }; - - useEffect(() => { - document.title = 'ShiftSync | Settings'; - }, []); - - useEffect(() => { - const handleResize = () => setWindowWidth(window.innerWidth); - window.addEventListener('resize', handleResize); - - // Initial trigger (in case something else needs it) - handleResize(); - - return () => { - window.removeEventListener('resize', handleResize); - }; - }, []); - - useEffect(() => { - if (pageValue?.id && pageRefs.current[pageValue.id]) { - const el = pageRefs.current[pageValue.id]; - const rect = el.getBoundingClientRect(); - const containerRect = el.parentNode.getBoundingClientRect(); - setIndicatorStyle({ - left: rect.left - containerRect.left, - width: rect.width - }); - } - }, [pageValue?.id, windowWidth, window.innerHeight]); - - useEffect(() => { - const filteredFields = settingsFields?.filter((field) => { - const hasAccess = - (field?.accessRequired === 'administrator' && isAdministrator) || - (field?.accessRequired === 'manager' && isManager) || - (field?.accessRequired === 'scheduler' && isScheduler) || - (!field?.accessRequired || field?.accessRequired === 'user'); - - return field?.tab === tabValue?.value && hasAccess; - }); - - if (filteredFields.length > 0) { - setPageValue(filteredFields[0]); - } else { - setPageValue(null); - } - }, [tabValue, isAdministrator, isManager, isScheduler]); - - useEffect(() => { - - }, [department]); - - return ( -
- {user?.administrator || user?.manager ? ( - - - - ) : null } - - {settingsFields?.filter((field) => field?.tab === tabValue?.value)?.filter((field) => { - return ((field?.accessRequired === 'administrator' && isAdministrator) || - (field?.accessRequired === 'manager' && isManager) || - (field?.accessRequired === 'scheduler' && isScheduler) || - (field?.accessRequired === 'user' || !field?.accessRequired)) - })?.map((field) => { - return ( - { pageRefs.current[field?.id] = el; }} - onClick={() => setPageValue(field)} - > - {field?.title} - - ) - })} - - - - - {pageValue?.cards?.map((card) => { - if ( - (card?.accessRequired === 'administrator' && isAdministrator) || - (card?.accessRequired === 'manager' && isManager) || - (card?.accessRequired === 'scheduler' && isScheduler) - ) { - return ( - - - {card?.label} - - {card?.fields?.find((field) => field?.type === 'header') !== undefined && ( -
- - - {card?.fields?.map((field) => { - return field?.type === 'header' && ( - -

- {field?.label}: -

-

- {department[field?.id]} -

-
- ) - })} -
-
- )} - -
{ - e.preventDefault(); - onSubmit(changedFields); - }} - > - - {!card?.removeEdit && ( - editMode === card?.id ? ( - setEditMode(null)}> - -

View

-
- ) : ( - setEditMode(card?.id)}> - -

Edit

-
- ) - )} -
- - f.type === 'transfer')} - > - {card?.fields?.map((field) => { - let fieldType; - if (field?.type === 'text') { - fieldType = handleChange(e, 'text')} - />; - } else if (field?.type === 'phone') { - fieldType = handleChange(e, 'phone')} - pattern="\(\d{3}\) \d{3}-\d{4}" - maxlength="14" - /> - } else if (field?.type === 'select') { - fieldType = ( - - {field?.options?.map((option) => { - const inputId = `${field.id}-${option.value}`; - return ( - - handleChange(e, 'text')} - /> - - {option?.label} - - - ) - })} - - ) - } else if (field?.type === 'transfer') { - fieldType = { - return onSubmit({ [field.id]: t }); - }} - /> - } - return field?.type !== 'header' && ( - - {field?.label ? ( - - {field?.label}: - - ) : null } - {fieldType} - - ) - })} - - - {card?.id === editMode && ( - - - - )} -
-
- ) - } - return null; - })} -
-
- ); -}; +import React, { useEffect, useRef, useState } from 'react'; +import styled from '@emotion/styled'; +import { Stack } from '@mui/material'; +import EditIcon from '@mui/icons-material/Edit'; +import EditOffIcon from '@mui/icons-material/EditOff'; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import { ToggleTabs, TransferBox, useLocalStore } from '@components'; +import { settingsFields } from './helpers'; + +const OuterContainer = styled(Stack)` + position: relative; + display: flex; + align-items: center; + flex-direction: row; + justify-content: center; + padding: 10px 10px 0px 0px; +`; + +const Border = styled('div')` + height: 1px; + width: 100%; + background-color: #A8A8A8; +`; + +const Tab = styled('div')` + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + height: 100%; + padding: 6px 16px; + font-size: 20px; + font-weight: 800; + color: grey; + background: none; + border: none; + cursor: pointer; + font-family: "WDXL Lubrifont TC"; + letter-spacing: .05em; + word-spacing: .2em; +`; + +const SlidingIndicator = styled('div')` + position: absolute; + height: 1px; + bottom: -1px; + background-color: #4D79FF; + transition: left 0.3s ease, width 0.3s ease; +`; + +const CardShell = styled('div')` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; +`; + +const Card = styled('div')` + background-color: #C7C7C7; + width: 50%; + min-width: 750px; + padding: 20px; + border-radius: 10px; + margin: 5px; +`; + +const CardTitle = styled('p')` + color: white; + font-weight: 400; + font-size: 20px; + font-family: "WDXL Lubrifont TC"; + padding-bottom: 5px; +`; + +const CardHeader = styled('div')` + display: flex; + justify-content: space-between; + flex-direction: row; + padding: 10px; +`; + +const EditArea = styled('div')` + display: flex; + flex-direction: row; + justify-content: flex-end; + padding-top: 10px; + color: #4D79FF; + font-weight: 600; +`; + +const EditTextButton = styled('div')` + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; + gap: 4px; + padding-bottom: 2px; + border-bottom: 2px solid transparent; + transition: border-bottom 0.2s ease; + + &:hover { + border-bottom: 2px solid #4D79FF; + } +`; + +const CardBody = styled('div')` + display: flex; + flex-direction: column; + align-items: center; +`; + +const InnerCard = styled('div')` + display: flex; + flex-direction: column; + padding: 10px; + width: 50%; + + ${({ centered }) => centered && ` + align-items: center; + `} +`; + +const InnerCardRow = styled('div')` + display: flex; + flex-direction: row; + padding: 5px; +`; + +const InnerCardRowLabel = styled('label')` + display: flex; + justify-content: flex-end; + text-align: right; + width: 60%; + padding-right: 10px; + font-size: 14px; + align-items: center; +`; + +const InnerCardRowInput = styled('input')` + display: flex; + justify-content: flex-end; + width: 100%; + padding: 4px; +`; + +const InnerCardRadioInput = styled('input')` + padding-right: 5px; +`; + +const InnerCardRadioLabel = styled('label')` + font-size: 14px; + padding-left: 5px; + align-items: center; +`; + +const InnerCardRowRadioDiv = styled('div')` + display: flex; + justify-content: space-evenly; + width: 100%; + padding: 4px; +`; + +const FormRadioButtonLabel = styled('label')``; + +const FormInputButtonDiv = styled('div')` + display: flex; + flex-direction: row; + justify-content: flex-end; + padding-top: 10px; +`; + +const FormInputButton = styled('input')` + padding: 4px 10px; + border-radius: 4px; +`; + +export const Settings = () => { + const { user, department, setDepartment } = useLocalStore(); + + const isAdministrator = user?.administrator; + const isManager = user?.manager; + const isScheduler = user?.scheduler; + + const originalDepartmentRef = useRef(department); + const [formValues, setFormValues] = useState(() => { + const initial = {}; + settingsFields.forEach(section => { + section.cards.forEach(card => { + card.fields.forEach(field => { + initial[field.id] = department?.[field.id] || ''; + }); + }); + }); + return initial; + }); + const pageRefs = useRef({}); + const tabs = [ + { + label: 'Personal', + value: 'personal' + }, + { + label: 'Department', + value: 'department' + } + ]; + + const [windowWidth, setWindowWidth] = useState(window.innerWidth); + const [editMode, setEditMode] = useState(null); + const [tabValue, setTabValue] = useState(tabs[0]); + const [pageValue, setPageValue] = useState({}); + const [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0 }); + + const getChangedFields = (original, current) => { + const changed = {}; + for (const key in current) { + if (current[key] !== original[key]) { + changed[key] = current[key]; + } + } + return changed; + }; + + const changedFields = getChangedFields(originalDepartmentRef.current, formValues); + const hasChanges = Object.keys(changedFields).length > 0; + + const onSubmit = (data) => { + setDepartment({ + ...department, + ...data + }); + originalDepartmentRef.current = { + ...originalDepartmentRef.current, + ...data + }; + setEditMode(null); + }; + + const formatPhoneNumber = (value) => { + const cleaned = value.replace(/\D/g, '').slice(0, 10); // Only digits, max 10 + const length = cleaned.length; + + if (length === 0) return ''; + if (length < 4) return `(${cleaned}`; + if (length < 7) return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3)}`; + return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`; + }; + + + const handleChange = (e, type) => { + let { name, value } = e.target; + if (type === 'phone') { + value = formatPhoneNumber(value); + } + setFormValues(prev => ({ ...prev, [name]: value })); + }; + + useEffect(() => { + document.title = 'ShiftSync | Settings'; + }, []); + + useEffect(() => { + const handleResize = () => setWindowWidth(window.innerWidth); + window.addEventListener('resize', handleResize); + + // Initial trigger (in case something else needs it) + handleResize(); + + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); + + useEffect(() => { + if (pageValue?.id && pageRefs.current[pageValue.id]) { + const el = pageRefs.current[pageValue.id]; + const rect = el.getBoundingClientRect(); + const containerRect = el.parentNode.getBoundingClientRect(); + setIndicatorStyle({ + left: rect.left - containerRect.left, + width: rect.width + }); + } + }, [pageValue?.id, windowWidth, window.innerHeight]); + + useEffect(() => { + const filteredFields = settingsFields?.filter((field) => { + const hasAccess = + (field?.accessRequired === 'administrator' && isAdministrator) || + (field?.accessRequired === 'manager' && isManager) || + (field?.accessRequired === 'scheduler' && isScheduler) || + (!field?.accessRequired || field?.accessRequired === 'user'); + + return field?.tab === tabValue?.value && hasAccess; + }); + + if (filteredFields.length > 0) { + setPageValue(filteredFields[0]); + } else { + setPageValue(null); + } + }, [tabValue, isAdministrator, isManager, isScheduler]); + + return ( +
+ {user?.administrator || user?.manager ? ( + + + + ) : null } + + {settingsFields?.filter((field) => field?.tab === tabValue?.value)?.filter((field) => { + return ((field?.accessRequired === 'administrator' && isAdministrator) || + (field?.accessRequired === 'manager' && isManager) || + (field?.accessRequired === 'scheduler' && isScheduler) || + (field?.accessRequired === 'user' || !field?.accessRequired)) + })?.map((field) => { + return ( + { pageRefs.current[field?.id] = el; }} + onClick={() => setPageValue(field)} + > + {field?.title} + + ) + })} + + + + + {pageValue?.cards?.map((card) => { + if ( + (card?.accessRequired === 'administrator' && isAdministrator) || + (card?.accessRequired === 'manager' && isManager) || + (card?.accessRequired === 'scheduler' && isScheduler) + ) { + return ( + + + {card?.label} + + {card?.fields?.find((field) => field?.type === 'header') !== undefined && ( +
+ + + {card?.fields?.map((field) => { + return field?.type === 'header' && ( + +

+ {field?.label}: +

+

+ {department[field?.id]} +

+
+ ) + })} +
+
+ )} + +
{ + e.preventDefault(); + onSubmit(changedFields); + }} + > + + {!card?.removeEdit && ( + editMode === card?.id ? ( + setEditMode(null)}> + +

View

+
+ ) : ( + setEditMode(card?.id)}> + +

Edit

+
+ ) + )} +
+ + f.type === 'transfer')} + > + {card?.fields?.map((field) => { + let fieldType; + if (field?.type === 'text') { + fieldType = handleChange(e, 'text')} + />; + } else if (field?.type === 'phone') { + fieldType = handleChange(e, 'phone')} + pattern="\(\d{3}\) \d{3}-\d{4}" + maxlength="14" + /> + } else if (field?.type === 'select') { + fieldType = ( + + {field?.options?.map((option) => { + const inputId = `${field.id}-${option.value}`; + return ( + + handleChange(e, 'text')} + /> + + {option?.label} + + + ) + })} + + ) + } else if (field?.type === 'transfer') { + fieldType = { + return onSubmit({ [field.id]: t }); + }} + /> + } + return field?.type !== 'header' && ( + + {field?.label ? ( + + {field?.label}: + + ) : null } + {fieldType} + + ) + })} + + + {card?.id === editMode && ( + + + + )} +
+
+ ) + } + return null; + })} +
+
+ ); +}; diff --git a/web/src/router/AppRouter.jsx b/web/src/router/AppRouter.jsx index 30939a2..df9f984 100644 --- a/web/src/router/AppRouter.jsx +++ b/web/src/router/AppRouter.jsx @@ -1,170 +1,170 @@ -import React, { useEffect, useState } from 'react'; -import { Routes, Route } from 'react-router-dom'; -import { Home, Profile, Schedule, Settings } from '@src/pages'; -import { Shell } from '@components'; -import { useLocalStore } from '@components'; -import { fetchAPI } from './axios.js'; - -const dept = { - id: 1, - company: 'Darien EMS - Post 53', - abv: 'DEMS', - billing_address: '0 Ledge Road', - town: 'Darien', - state: 'Connecticut', - postal: '06820', - country: 'United States', - phone: '', - display_time: '12', - start_day: 'sunday', - company_logo: '', - employee_count: 1, - subscription_expiration: '10/01/2025', - schedulers: [3], - managers: [2], - administrators: [1] -}; - -const users = [ - { - id: 1, - first_name: 'ShiftSync-Administrator', - last_name: 'Test-User', - email: 'testuserA@shift-sync.com', - accessLevel: 150, - is_ss_admin: false - }, - { - id: 2, - first_name: 'ShiftSync-Manager', - last_name: 'Test-User', - email: 'testuserM@shift-sync.com', - accessLevel: 100, - is_ss_admin: false - }, - { - id: 3, - first_name: 'ShiftSync-Scheduler', - last_name: 'Test-User', - email: 'testuserS@shift-sync.com', - accessLevel: 50, - is_ss_admin: false - }, - { - id: 4, - first_name: 'ShiftSync-User', - last_name: 'Test-User', - email: 'testuserU@shift-sync.com', - accessLevel: 1, - is_ss_admin: false - }, -]; - -const AppRouter = () => { - const { user, setUser, setDepartment } = useLocalStore(); - const [userChanged, setUserChanged] = useState(false); - - useEffect(() => { - const init = async () => { - const localVersion = localStorage.getItem("APP_VERSION"); - const currentVersion = window.APP_VERSION; - - if (localVersion && localVersion !== currentVersion) { - console.log("Version changed, forcing reload"); - localStorage.setItem("APP_VERSION", currentVersion); - window.location.reload(true); - return; - } else { - localStorage.setItem("APP_VERSION", currentVersion); - } - - const data = await fetchAPI('userData', 'get'); - console.log('data:', data); - - // TODO: Replace this with real data from your API - // const users = data?.users || []; // Example fix - // const dept = data?.dept || {}; // Example fix - - const employee_count = 1; - const subs_expiration = '10/22/2025'; - - setUser({ - ...users[0], - scheduler: dept?.schedulers?.includes(1), - manager: dept?.managers?.includes(1), - administrator: dept?.administrators?.includes(1) - }); - - const newAdministrators = dept?.administrators?.map((admin) => { - const user = users?.find((user) => user?.id === admin); - return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; - }); - - const newManagers = dept?.managers?.map((manager) => { - const user = users?.find((user) => user?.id === manager); - return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; - }); - - const newSchedulers = dept?.schedulers?.map((scheduler) => { - const user = users?.find((user) => user?.id === scheduler); - return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; - }); - - const newUsers = users?.map((user) => ({ - id: user?.id, - value: `${user?.last_name}, ${user?.first_name}` - })); - - setDepartment({ - ...dept, - users: newUsers, - schedulers: newSchedulers, - managers: newManagers, - administrators: newAdministrators, - employee_count, - subs_expiration - }); - }; - - init(); - }, []); - - useEffect(() => { - if (!userChanged && user) { - if (user?.is_ss_admin) { - setUser({ - ...user, - scheduler: true, - manager: true, - administrator: true, - }); - } else if (user?.administrator) { - setUser({ - ...user, - scheduler: true, - manager: true, - }); - } else if (user?.manager) { - setUser({ - ...user, - scheduler: true, - }); - } - setUserChanged(true); - } - }, [user]); - - - return ( - - - } /> - } /> - } /> - } /> - - - ); -}; - -export default AppRouter +import React, { useEffect, useState } from 'react'; +import { Routes, Route } from 'react-router-dom'; +import { Home, Profile, Schedule, Settings } from '@src/pages'; +import { Shell } from '@components'; +import { useLocalStore } from '@components'; +import { fetchAPI } from './axios.js'; + +const dept = { + id: 1, + company: 'Darien EMS - Post 53', + abv: 'DEMS', + billing_address: '0 Ledge Road', + town: 'Darien', + state: 'Connecticut', + postal: '06820', + country: 'United States', + phone: '', + display_time: '12', + start_day: 'sunday', + company_logo: '', + employee_count: 1, + subscription_expiration: '10/01/2025', + schedulers: [3], + managers: [2], + administrators: [1] +}; + +const users = [ + { + id: 1, + first_name: 'ShiftSync-Administrator', + last_name: 'Test-User', + email: 'testuserA@shift-sync.com', + accessLevel: 150, + is_ss_admin: false + }, + { + id: 2, + first_name: 'ShiftSync-Manager', + last_name: 'Test-User', + email: 'testuserM@shift-sync.com', + accessLevel: 100, + is_ss_admin: false + }, + { + id: 3, + first_name: 'ShiftSync-Scheduler', + last_name: 'Test-User', + email: 'testuserS@shift-sync.com', + accessLevel: 50, + is_ss_admin: false + }, + { + id: 4, + first_name: 'ShiftSync-User', + last_name: 'Test-User', + email: 'testuserU@shift-sync.com', + accessLevel: 1, + is_ss_admin: false + }, +]; + +const AppRouter = () => { + const { user, setUser, setDepartment } = useLocalStore(); + const [userChanged, setUserChanged] = useState(false); + + useEffect(() => { + const init = async () => { + const localVersion = localStorage.getItem("APP_VERSION"); + const currentVersion = window.APP_VERSION; + + if (localVersion && localVersion !== currentVersion) { + console.log("Version changed, forcing reload"); + localStorage.setItem("APP_VERSION", currentVersion); + window.location.reload(true); + return; + } else { + localStorage.setItem("APP_VERSION", currentVersion); + } + + const data = await fetchAPI('userData', 'get'); + console.log('data:', data); + + // TODO: Replace this with real data from your API + // const users = data?.users || []; // Example fix + // const dept = data?.dept || {}; // Example fix + + const employee_count = 1; + const subs_expiration = '10/22/2025'; + + setUser({ + ...users[0], + scheduler: dept?.schedulers?.includes(1), + manager: dept?.managers?.includes(1), + administrator: dept?.administrators?.includes(1) + }); + + const newAdministrators = dept?.administrators?.map((admin) => { + const user = users?.find((user) => user?.id === admin); + return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; + }); + + const newManagers = dept?.managers?.map((manager) => { + const user = users?.find((user) => user?.id === manager); + return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; + }); + + const newSchedulers = dept?.schedulers?.map((scheduler) => { + const user = users?.find((user) => user?.id === scheduler); + return { id: user?.id, value: `${user?.last_name}, ${user?.first_name}` }; + }); + + const newUsers = users?.map((user) => ({ + id: user?.id, + value: `${user?.last_name}, ${user?.first_name}` + })); + + setDepartment({ + ...dept, + users: newUsers, + schedulers: newSchedulers, + managers: newManagers, + administrators: newAdministrators, + employee_count, + subs_expiration + }); + }; + + init(); + }, []); + + useEffect(() => { + if (!userChanged && user) { + if (user?.is_ss_admin) { + setUser({ + ...user, + scheduler: true, + manager: true, + administrator: true, + }); + } else if (user?.administrator) { + setUser({ + ...user, + scheduler: true, + manager: true, + }); + } else if (user?.manager) { + setUser({ + ...user, + scheduler: true, + }); + } + setUserChanged(true); + } + }, [user]); + + + return ( + + + } /> + } /> + } /> + } /> + + + ); +}; + +export default AppRouter