Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/web/general integration #394

Merged
merged 96 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
b46aba6
chore: Add SecurityService for fetching and updating security settings
Tinashe-Austin Aug 26, 2024
9ea4e3a
chore: Update privacy policy link in AboutComponent
Tinashe-Austin Aug 26, 2024
e1aef07
chore: Update security settings
Tinashe-Austin Aug 26, 2024
31ee56e
chore: Update SideNav component with Booking option
Tinashe-Austin Aug 26, 2024
fdf3b47
3D dependencies added
Tinashe-Austin Sep 10, 2024
c06d2cf
Chnages to add proxy for ai intergration
Tinashe-Austin Sep 10, 2024
c942675
chore: Add AIDataService for AI integration
Tinashe-Austin Sep 10, 2024
70aa501
feat: Add API functions for uploading room images and getting image URLs
Tinashe-Austin Sep 10, 2024
58bbdf4
reverted protected routes due to error, wil revert back once fixed
Tinashe-Austin Sep 10, 2024
22c9a80
Graph AI Intergrated
Tinashe-Austin Sep 10, 2024
f258fb1
Intergrated AI data
Tinashe-Austin Sep 10, 2024
e548f2b
Using AI user stats
Tinashe-Austin Sep 10, 2024
7414e86
Uses AI data
Tinashe-Austin Sep 10, 2024
bd2f7d4
chore: Update Visitations component with 3D visualization of building…
Tinashe-Austin Sep 10, 2024
d49fbe1
feat: Add API functions for uploading room images and getting image URLs
Tinashe-Austin Sep 10, 2024
ee2efed
chore: slight dropdown adjustments
Tinashe-Austin Sep 10, 2024
fc69e9c
Top Nav fix
Tinashe-Austin Sep 11, 2024
2064956
collecting and storing more user details
Tinashe-Austin Sep 11, 2024
26d7b38
attempt at getting keystats from analytics data
Tinashe-Austin Sep 11, 2024
ac09b4d
interim fix, not complete, trying to get data from the analytics for …
Tinashe-Austin Sep 11, 2024
750aefd
Profile avatar, attempt at put requests
Tinashe-Austin Sep 11, 2024
3bbc515
Tab fix
Tinashe-Austin Sep 11, 2024
9ef2560
Collect Worker Stats
Tinashe-Austin Sep 16, 2024
972ba3f
collect user ststs
Tinashe-Austin Sep 16, 2024
ad15342
charts that summarize the user data in modal
Tinashe-Austin Sep 16, 2024
65b9e87
new graphics for loader
Tinashe-Austin Sep 16, 2024
d3165d5
More analysis graphics
Tinashe-Austin Sep 16, 2024
0225b97
Changes to incoorperate user dtata from backend
Tinashe-Austin Sep 16, 2024
f388ef1
add additional information for data analytics
Tinashe-Austin Sep 16, 2024
9f64c5e
Additional API Calls
Tinashe-Austin Sep 17, 2024
6c7c8ca
updated imports
Tinashe-Austin Sep 17, 2024
9d941d2
Add ActiveEmployeeCard component for displaying most active employee …
Tinashe-Austin Sep 17, 2024
eddb468
Add AverageHoursChart component for displaying average hours by weekd…
Tinashe-Austin Sep 17, 2024
012da4c
Add HoursDashboard component for displaying daily hours worked statis…
Tinashe-Austin Sep 17, 2024
9b4c8ff
Add LeastActiveEmployeeCard component for displaying least active emp…
Tinashe-Austin Sep 17, 2024
cae08f6
Add MostActiveEmployeeCard component for displaying most active emplo…
Tinashe-Austin Sep 17, 2024
b2e0e94
Add PeakOfficeHoursChart component for displaying peak office hours b…
Tinashe-Austin Sep 17, 2024
4b48bcd
Add WorkerDashboard component for displaying worker statistics
Tinashe-Austin Sep 17, 2024
9be8e0a
Add WorkRatioChart component for displaying work ratio by weekday sta…
Tinashe-Austin Sep 17, 2024
d4d362f
Merge branch 'develop' of https://github.com/COS301-SE-2024/occupi in…
waveyboym Sep 21, 2024
1ebeebe
Refactor App component to handle theme and authentication state
waveyboym Sep 21, 2024
abee6ca
Add @react-three/postprocessing package for post-processing effects i…
Tinashe-Austin Sep 21, 2024
adf0034
Refactor component imports and add new user statistics components
Tinashe-Austin Sep 21, 2024
1abf72f
Add BookingLevelCalendar component for displaying a calendar with boo…
Tinashe-Austin Sep 21, 2024
0f3bf2e
Add BuildingTower component for displaying a 3D building with dynamic…
Tinashe-Austin Sep 21, 2024
9e19ff8
Add AvgArrDep component for displaying average arrival and departure …
Tinashe-Austin Sep 21, 2024
99edfb8
Add UserStatsComponent for displaying user statistics and fetching da…
Tinashe-Austin Sep 21, 2024
a251fb5
Add BarChartComponent for displaying a bar chart with data
Tinashe-Austin Sep 21, 2024
9f9acbc
Refactor import statements in Modal component
Tinashe-Austin Sep 21, 2024
6cb545a
Add PieChartComponent for displaying a pie chart with data
Tinashe-Austin Sep 21, 2024
eeb504f
Add PieChartPeakHoursComponent for displaying a pie chart with peak h…
Tinashe-Austin Sep 21, 2024
09fd188
Add UserHoursCharts component for displaying user hours data in a bar…
Tinashe-Austin Sep 21, 2024
1d53234
Add UserPeakOfficeHoursChart component for displaying user peak offic…
Tinashe-Austin Sep 21, 2024
9052df6
Add OccupancyRecommendationEngine component for analyzing occupancy d…
Tinashe-Austin Sep 21, 2024
a669460
Refactor file structure and imports for UserWorkRatioChart component
Tinashe-Austin Sep 21, 2024
5a0e6d8
Merge branch 'fix/web/General-Integration' of https://github.com/COS3…
Tinashe-Austin Sep 21, 2024
32ea1b6
Refactor file structure and imports for UserWorkRatioChart component
Tinashe-Austin Sep 21, 2024
314517d
new dependancy
Tinashe-Austin Sep 22, 2024
c4fbea9
Reverted this feroRoutes stuff gosh, will fix later, PC going crazy
Tinashe-Austin Sep 22, 2024
ee9e6a7
Fix type annotation in CentrifugoService.ts
Tinashe-Austin Sep 22, 2024
59bc157
Refactor component imports and add new components
Tinashe-Austin Sep 22, 2024
ac7d35c
Refactor BuildingTower component and adjust rotation speed
Tinashe-Austin Sep 22, 2024
cf7a470
Refactor EmployeeSummaryCard component to display most and least acti…
Tinashe-Austin Sep 22, 2024
f802f39
Refactor WorkerDashboard component and add WorkerStatsDashboard compo…
Tinashe-Austin Sep 22, 2024
e6ed165
Refactor AiDashboard component imports and add new components
Tinashe-Austin Sep 22, 2024
3c82110
Refactor Visitations component and add Building Overview, Booking Cal…
Tinashe-Austin Sep 22, 2024
4ea15b8
Refactor App.tsx to add BookingStats and WorkerStatsDashboard components
Tinashe-Austin Sep 22, 2024
d22d000
Add Worker icon to assets
Tinashe-Austin Sep 22, 2024
b71a026
Refactor Report icon component
Tinashe-Austin Sep 22, 2024
80ba520
Add Worker icon component
Tinashe-Austin Sep 22, 2024
d9912dd
Refactor SideNav component to add Booking Statistics and Worker Dashb…
Tinashe-Austin Sep 22, 2024
245a677
Refactor WorkerDashboard component and add BookingStats component
Tinashe-Austin Sep 22, 2024
480f293
Refactor AiDashboard component to remove unused imports and update co…
Tinashe-Austin Sep 22, 2024
1bf440c
Refactor BookingStats component and add Booking Statistics page
Tinashe-Austin Sep 22, 2024
5b55fd0
Refactor Visitations component to add TopNav and color legend
Tinashe-Austin Sep 22, 2024
101feee
Refactor WorkerDashboard component and add BookingStats component
Tinashe-Austin Sep 22, 2024
d39240b
Refactor package.json to add react-iconly dependency, other stuff add…
Tinashe-Austin Sep 24, 2024
9812f71
linting fix
Tinashe-Austin Sep 24, 2024
ff059c1
Refactor CentrifugoService and WorkerStatsService
Tinashe-Austin Sep 25, 2024
f281295
Refactor BookingLevelCalendar and CapacityComparisonBarChart components
Tinashe-Austin Sep 25, 2024
28d0105
Refactor OccupancyModal and UserHoursCharts components
Tinashe-Austin Sep 25, 2024
ac0db1c
Refactor UserPeakOfficeHoursChart and UserStatsReport components
Tinashe-Austin Sep 25, 2024
b8ead0e
Refactor UserStatsTypes component
Tinashe-Austin Sep 25, 2024
39c81af
Refactor TopNav component to remove unused FaBars import,
Tinashe-Austin Sep 25, 2024
7b5de07
linting error fix
Tinashe-Austin Sep 25, 2024
33f25d6
Tests that need to be refactored
Tinashe-Austin Sep 25, 2024
8761ad1
Merge branch 'develop' into fix/web/General-Integration
Tinashe-Austin Sep 25, 2024
789a578
Refactor UserStatsReport component to handle missing data and improve…
Tinashe-Austin Sep 25, 2024
17f6ce4
Merge branch 'develop' into fix/web/General-Integration
Tinashe-Austin Sep 25, 2024
02e2604
Update TopNav.tsx
waveyboym Sep 25, 2024
9ee0cea
Refactor TopNav component to increase z-index value and improve code …
Tinashe-Austin Sep 25, 2024
51e782c
Merge branch 'fix/web/General-Integration' of https://github.com/COS3…
Tinashe-Austin Sep 25, 2024
33ea80f
Refactor imports in KeyStats.tsx and AverageHoursChart.tsx
Tinashe-Austin Sep 25, 2024
c6c39ca
Refactor PeakOfficeHoursChart and WorkRatioChart components to use ty…
Tinashe-Austin Sep 25, 2024
4b33acd
Showed the typescript devs who the REAL programmer is!!!
waveyboym Sep 25, 2024
9404292
linting fixes
Tinashe-Austin Sep 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified frontend/occupi-web/bun.lockb
Binary file not shown.
6 changes: 6 additions & 0 deletions frontend/occupi-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
"@passwordless-id/webauthn": "^1.6.1",
"@radix-ui/react-checkbox": "^1.1.1",
"@react-pdf/renderer": "^3.4.4",
"@react-three/drei": "^9.111.5",
"@react-three/fiber": "^8.17.6",
"@react-three/postprocessing": "^2.16.2",
"@remixicon/react": "^4.2.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
Expand All @@ -37,6 +40,7 @@
"@types/prop-types": "^15.7.12",
"@types/react-beautiful-dnd": "^13.1.8",
"@types/react-grid-layout": "^1.3.5",
"@types/uuid": "^10.0.0",
"axios": "^1.7.2",
"axios-cookiejar-support": "^5.0.2",
"body-parser": "^1.20.2",
Expand Down Expand Up @@ -66,7 +70,9 @@
"react-dnd-test-backend": "^16.0.1",
"react-dnd-test-utils": "^16.0.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
"react-grid-layout": "^1.4.4",
"react-iconly": "^2.2.10",
"react-icons": "^5.2.1",
"react-pdf-charts": "^0.2.5",
"react-rnd": "^10.4.11",
Expand Down
67 changes: 67 additions & 0 deletions frontend/occupi-web/src/AiDataService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import axios from 'axios';

const BASE_URL = 'https://ai.occupi.tech';

interface PredictionData {
Day_of_Week: number;
Day_of_month: number;
Is_Weekend: boolean;
Month: number;
Predicted_Attendance_Level: string;
Predicted_Class: number;
Special_Event: number;
}

const AIDataService = {
checkStatus: async () => {
try {
const response = await axios.get(`${BASE_URL}/`);
return response.data;
} catch (error) {
console.error('Error checking API status:', error);
throw error;
}
},

getPredictionForToday: async (): Promise<PredictionData> => {
try {
const response = await axios.get<PredictionData>(`${BASE_URL}/predict`);
return response.data;
} catch (error) {
console.error('Error fetching today\'s prediction:', error);
throw error;
}
},

getPredictionForWeek: async (): Promise<PredictionData[]> => {
try {
const response = await axios.get<PredictionData[]>(`${BASE_URL}/predict_week`);
return response.data;
} catch (error) {
console.error('Error fetching week prediction:', error);
throw error;
}
},

getPredictionForDate: async (date: string): Promise<PredictionData> => {
try {
const response = await axios.get<PredictionData>(`${BASE_URL}/predict_date`, { params: { date } });
return response.data;
} catch (error) {
console.error('Error fetching prediction for date:', error);
throw error;
}
},

getPredictionForWeekFromDate: async (date: string): Promise<PredictionData[]> => {
try {
const response = await axios.get<PredictionData[]>(`${BASE_URL}/predict_week_from_date`, { params: { date } });
return response.data;
} catch (error) {
console.error('Error fetching week prediction from date:', error);
throw error;
}
},
};

export default AIDataService;
30 changes: 30 additions & 0 deletions frontend/occupi-web/src/Api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// src/services/api.ts

import axios from 'axios';

const api = axios.create({
baseURL: '/api',
});

export const uploadRoomImage = async (imageFile: File, roomId: string) => {
const formData = new FormData();
formData.append('image', imageFile);
formData.append('roomId', roomId);

try {
const response = await api.post('/upload-room-image', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
return response.data;
} catch (error) {
console.error('Error uploading image:', error);
throw error;
}
};
export const getImageUrl = (imageId: string, quality: string = 'mid') => {
return `/api/image/${imageId}?quality=${quality}`;
};

export default api;
182 changes: 47 additions & 135 deletions frontend/occupi-web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,157 +1,69 @@
import {
LoginForm,
OtpPage,
Settings,
Dashboard,
Analysis,
Visitation,
Faq,
AiDashboard,
Rooms,
AboutPage,
SecurityPage,
ForgotPassword,
ResetPassword,
} from "@pages/index";
import {
Appearance,
OverviewComponent,
BookingComponent,
PDFReport,
ProfileView,
} from "@components/index";
import { LoginForm, OtpPage, Settings, Dashboard, Analysis, Visitation, Faq, AiDashboard, Rooms, AboutPage, SecurityPage,BookingStats ,WorkerStatsDashboard} from "@pages/index";
import { Appearance, OverviewComponent, BookingComponent, PDFReport, ProfileView } from "@components/index";
import { Layout } from "@layouts/index";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { useEffect, useState } from "react";
import { NotificationsSettings } from "@pages/notificationsSettings/NotificationsSettings";
import { FaroRoutes } from "@grafana/faro-react";
import ProtectedRoutes from "@components/protectedRoutes/ProtectedRoutes";
import { Navigate } from "react-router";

function App() {
// Initialize the theme state with system preference
const [theme] = useState(() => {
const savedTheme = localStorage.getItem("theme") || "system";
const [theme, ] = useState(() => {
const savedTheme = localStorage.getItem('theme') || 'system';
return savedTheme;
});
const [isAuthenticated] = useState(() => {
// Retrieve user storage from localStorage
const userStorage = localStorage.getItem("user-storage");

// Parse the userStorage if it exists
if (userStorage) {
const parsedUserStorage = JSON.parse(userStorage);
// Check if the email in userDetails is null or empty
return parsedUserStorage?.state?.userDetails?.email ? true : false;
}

return false;
});
useEffect(() => {
const applyTheme = (theme: string) => {
if (theme === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
document.documentElement.classList.toggle(
"dark",
systemTheme === "dark"
);
const applyTheme = (theme: string ) => {
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
document.documentElement.classList.toggle('dark', systemTheme === 'dark');
} else {
document.documentElement.classList.toggle("dark", theme === "dark");
document.documentElement.classList.toggle('dark', theme === 'dark');
}
};

applyTheme(theme);
localStorage.setItem("theme", theme);
localStorage.setItem('theme', theme);
}, [theme]);
return (
<Router>
<FaroRoutes>
<Route
path="/"
element={
isAuthenticated ? (
<Navigate to="/dashboard/overview" />
) : (
<LoginForm />
)
}
/>
<Route
path="/otp"
element={
isAuthenticated ? (
<Navigate to="/dashboard/overview" />
) : (
<OtpPage />
)
}
/>
<Route
path="/forgot-password"
element={
isAuthenticated ? (
<Navigate to="/dashboard/overview" />
) : (
<ForgotPassword />
)
}
/>
<Route
path="/reset-password"
element={
isAuthenticated ? (
<Navigate to="/dashboard/overview" />
) : (
<ResetPassword />
)
}
/>
<Route
path="/*"
element={
<ProtectedRoutes>
<Layout>
<Routes>
<Route path="dashboard/*" element={<Dashboard />}>
<Route path="overview" element={<OverviewComponent />} />
<Route path="bookings" element={<BookingComponent />} />
<Route path="visitations" element={<Visitation />} />
<Route path="analysis" element={<Analysis />} />
</Route>
<Route path="reports" element={<PDFReport />} />
{/**attach appropriate component */}
<Route path="faq" element={<Faq />} />
{/**attach appropriate component */}
<Route path="ai-dashboard" element={<AiDashboard />} />
{/**consider making ths its own page */}
<Route path="rooms" element={<Rooms />} />
{/**attach appropriate component */}
{/* <Route path="notifications" element={<Notifications />} />*attach appropriate component */}
<Routes>
<Route path="/" element={<LoginForm />} />
<Route path="/otp" element={<OtpPage />} />

<Route path="/*" element={
<Layout>
<Routes>
<Route path="dashboard/*" element={<Dashboard />} >
<Route path="overview" element={<OverviewComponent />} />
<Route path="bookings" element={<BookingComponent />} />*attach appropriate component
<Route path="visitations" element={<Visitation />} />{/**attach appropriate component */}
<Route path="analysis" element={<Analysis/>} />{}
</Route>

<Route path="reports" element={<PDFReport />} />{/**attach appropriate component */}
<Route path="faq" element={ <Faq/> } />{/**attach appropriate component */}
<Route path="ai-dashboard" element={<AiDashboard />} />{/**consider making ths its own page */}
<Route path="rooms" element={<Rooms />} />{/**attach appropriate component */}
{/* <Route path="notifications" element={<Notifications />} />*attach appropriate component */}
<Route path="bookingStats" element={<BookingStats />} />{/**attach appropriate component */}
<Route path="worker-dashboard" element={<WorkerStatsDashboard />} />{/**attach appropriate component */}


<Route path="settings/*" element={<Settings />}>
<Route path="profile" element={<ProfileView />} />
{/**attach appropriate component */}
<Route path="appearance" element={<Appearance />} />
<Route
path="notifications"
element={<NotificationsSettings />}
/>
{/**attach appropriate component */}
<Route path="security" element={<SecurityPage />} />
{/**attach appropriate component */}
<Route path="about" element={<AboutPage />} />
{/**attach appropriate component */}
</Route>
</Routes>
</Layout>
</ProtectedRoutes>
}></Route>
</FaroRoutes>

<Route path="settings/*" element={<Settings />}>
<Route path="profile" element={<ProfileView />} />{/**attach appropriate component */}
<Route path="appearance" element={<Appearance />} />
<Route path="notifications" element={<NotificationsSettings />} />{/**attach appropriate component */}
<Route path="security" element={<SecurityPage />} />{/**attach appropriate component */}
<Route path="about" element={<AboutPage />} />{/**attach appropriate component */}
</Route>
</Routes>
</Layout>}>
</Route>
</Routes>
</Router>
);
)
}

export default App;
export default App
54 changes: 54 additions & 0 deletions frontend/occupi-web/src/SecurityService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import axios from 'axios';

export interface SecuritySettings {
useBiometrics: boolean;
use2FA: boolean;
forceLogoutOnAppClose: boolean;
}

export const getSecuritySettings = async (email: string): Promise<{ data: SecuritySettings }> => {
try {
const response = await axios.get('/api/get-security-settings', {
params: {
email,
},
});
return response.data;
} catch (error) {
console.error('Error fetching security settings:', error);
throw error;
}
};

export const updateSecuritySettings = async (data: {
email: string;
mfa: 'on' | 'off';
currentPassword: string;
newPassword: string;
newPasswordConfirm: string;
}): Promise<{ data: null }> => {
try {
const response = await axios.post('/api/update-security-settings', data);
return response.data;
} catch (error) {
console.error('Error updating security settings:', error);
if (axios.isAxiosError(error)) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error('Response data:', error.response.data);
console.error('Response status:', error.response.status);
console.error('Response headers:', error.response.headers);
} else if (error.request) {
// The request was made but no response was received
console.error('No response received:', error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.error('Error setting up request:', error.message);
}
} else {
console.error('Unexpected error:', error);
}
throw error;
}
};
Empty file.
Loading