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

Pull dev branch changes into CHE-167 Story branch #146

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
f9692ca
CHE-155 Updated dev compose to spin up a postgres db container
brok3turtl3 May 14, 2024
d05689f
CHE-155 Added depends_on directive
brok3turtl3 May 14, 2024
e62b749
CHE-155 Testing database hook ups
brok3turtl3 May 15, 2024
694c559
CHE-155 pushing up code to bring another station
brok3turtl3 May 15, 2024
6313c8c
CHE-155 test commits
brok3turtl3 May 15, 2024
a371b98
CHE-155 Database connection established in dev container
brok3turtl3 May 15, 2024
d3fd3b9
CHE-155 CHanging approach to facilitate db seeding
brok3turtl3 May 16, 2024
41606a0
CHE-155 Placeholder Applications page, Router hooked up and basic api…
brok3turtl3 May 16, 2024
24aa0a1
CHE-155 Removed unnecessary logs, imorts and empty lines
brok3turtl3 May 16, 2024
b61eb7e
Merge pull request #112 from Code-Hammers/CHE-155/subtask/Create-Post…
brok3turtl3 May 16, 2024
c8c7b2f
CHE-157 Expanded on applications tables
brok3turtl3 May 17, 2024
1f3dbdf
Merge branch 'CHE-140/epic/Create-Job-Application-Tracker' into CHE-1…
brok3turtl3 May 17, 2024
32d636d
CHE-159 Created basic CreateApplicationPage
brok3turtl3 May 17, 2024
6f144e9
CHE-159 Added Create Application button and hooked up routing to Crea…
brok3turtl3 May 17, 2024
0800b0a
Merge pull request #115 from Code-Hammers/CHE-157/task/Update-Postgre…
brok3turtl3 May 18, 2024
4d5f33c
Merge branch 'CHE-141/story/Create-New-Application' into CHE-159/subt…
brok3turtl3 May 18, 2024
2d3bc44
CHE-159 Added local state for formData, handleChange functionality an…
brok3turtl3 May 18, 2024
58a05e4
CHE-159 Murdered a period
brok3turtl3 May 18, 2024
1ca4ab3
CHE-159 Added more input fields
brok3turtl3 May 18, 2024
b670661
CHE-159 Remaining fields added to initial form set up
brok3turtl3 May 18, 2024
9182764
CHE-159 Implemented status dropdown and dynamic database fetching for…
brok3turtl3 May 18, 2024
3ca6e9a
CHE-159 Removed boken comment code
brok3turtl3 May 18, 2024
8d5e48d
CHE-160 Built basic applicationSlice, added typing and hooked up to s…
brok3turtl3 May 18, 2024
b9e6862
Built basic applicationsSlice and hooked up to store
brok3turtl3 May 18, 2024
053cdbf
Merge pull request #117 from Code-Hammers/CHE-160/subtask/Implement-R…
brok3turtl3 May 18, 2024
3a507e8
Merge branch 'CHE-141/story/Create-New-Application' into CHE-159/subt…
brok3turtl3 May 18, 2024
7bddf1c
Merge pull request #116 from Code-Hammers/CHE-159/subtask/Create-New-…
brok3turtl3 May 18, 2024
98aec82
CHE-161 Updated submit button to show a status, added onSubmit to for…
brok3turtl3 May 18, 2024
6631292
CHE-161 Added createApplication controller and required route
brok3turtl3 May 19, 2024
7484da0
CHE-161 troubleshooting
brok3turtl3 May 19, 2024
3912bd0
CHE-161 Updates made to seeder script and some field names
brok3turtl3 May 19, 2024
e2507d7
CHE-161 Class name re-org
brok3turtl3 May 19, 2024
be579cf
Merge pull request #118 from Code-Hammers/CHE-161/subtask/Complete-Su…
brok3turtl3 May 19, 2024
374d1fb
Merge pull request #119 from Code-Hammers/CHE-141/story/Create-New-Ap…
brok3turtl3 May 19, 2024
9386208
CHE-143 Added update button to individual application info
brok3turtl3 May 19, 2024
ce7b707
CHE-143 Added navigation, routing and UpdateApplication page with bas…
brok3turtl3 May 19, 2024
80eaff0
CHE-143 Created route and controller for updates
brok3turtl3 May 19, 2024
957af17
CHE-143 Updated Redux slice and UpdateApplication component to us Red…
brok3turtl3 May 19, 2024
f62b3f9
CHE-143 Updates throughout entire flow to debug
brok3turtl3 May 20, 2024
0ba6df6
CHE-143 Updated code to only show current user's applications
brok3turtl3 May 20, 2024
bef2d07
CHE-143 Console logs clean up
brok3turtl3 May 20, 2024
fbd28dc
CHE-143 job_id add to formData to satisfy typing
brok3turtl3 May 20, 2024
edd56da
CHE-143 update to GitHub workflow file to specify Node environment
brok3turtl3 May 20, 2024
57be9a3
Merge branch 'dev' into CHE-140/epic/Create-Job-Application-Tracker
brok3turtl3 May 22, 2024
86bc941
Merge branch 'CHE-140/epic/Create-Job-Application-Tracker' into CHE-1…
brok3turtl3 May 22, 2024
4f8ef00
Merge pull request #120 from Code-Hammers/CHE-143/story/Update-Applic…
brok3turtl3 May 24, 2024
f104853
CHE-144 Route and controller added for getAggregatedUserStats
brok3turtl3 Jun 1, 2024
b1286f7
CHE-144 ApplicationDashBoard component created
brok3turtl3 Jun 1, 2024
145e9e0
CHE-144 Added dashboard componet to main page and fixed a fetch all e…
brok3turtl3 Jun 1, 2024
f9cc755
CHE-144 Updated styling
brok3turtl3 Jun 1, 2024
a02c014
CHE-144 Updated API calls to handle nulls
brok3turtl3 Jun 2, 2024
0c54fc9
CHE-144 Refactor to remove unnecessary database call
brok3turtl3 Jun 4, 2024
019cf4b
CHE-144 Refactored to use params in place of query
brok3turtl3 Jun 4, 2024
d0efa8d
CHE-144 Some temporary state handling for loading/errors until migrat…
brok3turtl3 Jun 4, 2024
8461fad
CHE-144 Added some temporary conditional rendering logic based on state
brok3turtl3 Jun 4, 2024
eb6367a
CHE-144 Quick auth and security refactors
brok3turtl3 Jun 4, 2024
74c1ff2
CHE-144 typing updates
brok3turtl3 Jun 4, 2024
afbf3cf
CHE-144 typing updates
brok3turtl3 Jun 4, 2024
027f83f
Quick logic patch for auth comparison
brok3turtl3 Jun 5, 2024
9481c12
Merge pull request #127 from Code-Hammers/CHE-144/story/View-User-Sta…
brok3turtl3 Jun 6, 2024
5bf274c
dev merge
brok3turtl3 Jun 7, 2024
0ce80fe
CHE-140 temp image change
brok3turtl3 Jun 7, 2024
4ef0807
CHE-140 Post merge clean up
brok3turtl3 Jun 7, 2024
59917c9
Merge branch 'CHE-140/epic/Create-Job-Application-Tracker' of https:/…
brok3turtl3 Jun 7, 2024
cfc7b87
CHE-189 Updated SQL tables
brok3turtl3 Jun 7, 2024
6049a2e
CHE-189 Added updateNotificationsPeriod controller
brok3turtl3 Jun 7, 2024
f22d3ed
CHE-189 Added pauseNotifications controller
brok3turtl3 Jun 7, 2024
0c649df
CHE-189 Updated exports and router
brok3turtl3 Jun 7, 2024
20119fc
CHE-189 Updated getAllApplications controller for new fields
brok3turtl3 Jun 7, 2024
b1a30c5
CHE-189 Updated createApplication controller to set last_updated fiel…
brok3turtl3 Jun 7, 2024
ac0aecd
CHE-189 Updated updateApplication controller to update last_updated f…
brok3turtl3 Jun 7, 2024
09687cf
CHE-189 Added notification functionality to ApplicationPage
brok3turtl3 Jun 7, 2024
8cd9e8c
CHE-189 Typing updates and fixes
brok3turtl3 Jun 7, 2024
e2a5c04
CHE-189 Updated database seeding
brok3turtl3 Jun 7, 2024
2512d23
CHE-189 Adjusted time checks for testing
brok3turtl3 Jun 7, 2024
edeb8b3
CHE-189 Pause notifications functionality added
brok3turtl3 Jun 7, 2024
4fbe93d
CHE-189 Added inactivity period controls for user
brok3turtl3 Jun 8, 2024
9a4c998
CHE-189 Adjusted auth check logic for updates and period calculations…
brok3turtl3 Jun 8, 2024
fc44442
CHE-189 Code clean up for linter
brok3turtl3 Jun 8, 2024
be2cdf8
Code cleanup for linter
brok3turtl3 Jun 8, 2024
99b15da
Further linting clean up
brok3turtl3 Jun 8, 2024
192adad
shakes fist at linter
brok3turtl3 Jun 8, 2024
f9d07a8
Prettier formatting updates
brok3turtl3 Jun 8, 2024
a0bd196
Merge pull request #136 from Code-Hammers/epic-remote-update
brok3turtl3 Jun 8, 2024
14f1532
Merge branch 'CHE-140/epic/Create-Job-Application-Tracker' into CHE-1…
brok3turtl3 Jun 8, 2024
72307e0
CHE-189 Merge resolutions
brok3turtl3 Jun 8, 2024
78530d3
CHE-189 Linter battle
brok3turtl3 Jun 8, 2024
8078b75
CHE-189 Code cleanup
brok3turtl3 Jun 9, 2024
e3c9a35
CHE-192 Updated getAllApplications to handle optional filter paramete…
brok3turtl3 Jun 9, 2024
2fd76b4
CHE-192 Application page updated with toggles for filters
brok3turtl3 Jun 9, 2024
f185cde
Merge pull request #135 from Code-Hammers/CHE-189/story/Create-Inacti…
brok3turtl3 Jun 9, 2024
d2e2ebe
Merge branch 'CHE-140/epic/Create-Job-Application-Tracker' into CHE-1…
brok3turtl3 Jun 9, 2024
ea52856
CHE-192 Debugging logic
brok3turtl3 Jun 9, 2024
542c8c8
CHE-192 Code tweaks to ensure stamps are consistent across files
brok3turtl3 Jun 10, 2024
fd5e428
CHE-192 Code cleanup
brok3turtl3 Jun 10, 2024
46a19db
CHE-192 Typing update
brok3turtl3 Jun 10, 2024
c5e6b43
CHE-192 Typing...
brok3turtl3 Jun 10, 2024
541811c
CHE-192 Updated image for lint and test compose, added credentials fo…
brok3turtl3 Jun 11, 2024
e80982e
Merge remote-tracking branch 'origin/CHE-192/story/Create-Filters' in…
brok3turtl3 Jun 11, 2024
3b5f0c2
CHE-192 Basic validation that stops user from picking a future date w…
brok3turtl3 Jun 11, 2024
d5090c2
Merge pull request #139 from Code-Hammers/CHE-192/story/Create-Filters
brok3turtl3 Jun 11, 2024
f5d95f9
CHE-140 Docker cleanup
brok3turtl3 Jun 13, 2024
8cd003e
CHE-140 image updates
brok3turtl3 Jun 13, 2024
822a378
CHE-140 Update docker-remove-all script files
brok3turtl3 Jun 13, 2024
74f4dd2
Merge pull request #144 from Code-Hammers/CHE-140/epic/Create-Job-App…
brok3turtl3 Jun 14, 2024
174f8c5
Merge branch 'dev' of https://github.com/Code-Hammers/code-hammers in…
seantokuzo Jun 15, 2024
3e6bc86
Merge branch 'CHE-167/story/BE-Refactor-Error-Handling' of https://gi…
seantokuzo Jun 15, 2024
c9e1dd0
update github workflows image version v2 -> v3
seantokuzo Jun 15, 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
10 changes: 7 additions & 3 deletions .github/workflows/build-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ jobs:
JWT_SECRET: ${{ secrets.JWT_SECRET }}
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18.17.1'
- name: Build Docker Image
run: docker build -t codehammers/ch-dev-dep-v2:latest -f Dockerfile-dev .
run: docker build -t codehammers/ch-dev-dep-v3:latest -f Dockerfile-dev .
- name: Install Root Dependencies
run: docker run codehammers/ch-dev-dep-v2:latest npm install
run: docker run codehammers/ch-dev-dep-v3:latest npm install
- name: Install Client Dependencies
run: docker run codehammers/ch-dev-dep-v2:latest /bin/sh -c "cd client && npm install"
run: docker run codehammers/ch-dev-dep-v3:latest /bin/sh -c "cd client && npm install"
- run: LINT_COMMAND=lint docker-compose -f docker-compose-lint.yml up --abort-on-container-exit
- run: docker-compose -f docker-compose-test.yml up --abort-on-container-exit
env:
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile-postgres
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM postgres:16.3

COPY ./scripts/sql_db_init.sql /docker-entrypoint-initdb.d/
9 changes: 7 additions & 2 deletions client/src/AuthenticatedApp.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { Route, Routes } from 'react-router-dom';
import { Route, Routes, useNavigate } from 'react-router-dom';
import Header from './components/Header/Header';
import MainPage from './pages/MainPage/MainPage';
import Forums from './pages/Forums/Forums';
Expand All @@ -8,7 +8,9 @@ import Profile from './pages/Profile/Profile';
import EditProfilePage from './pages/EditProfilePage/EditProfilePage';
import Directory from './pages/DirectoryPage/DirectoryPage';
import NotFoundPage from './pages/NotFoundPage/NotFoundPage';
import { useNavigate } from 'react-router-dom';
import ApplicationsPage from './pages/ApplicationsPage/ApplicationsPage';
import CreateApplicationPage from './pages/CreateApplicationPage/CreateApplicationPage';
import UpdateApplicationPage from './pages/UpdateApplicationPage/UpdateApplicationPage';

const AuthenticatedApp = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -44,6 +46,9 @@ const AuthenticatedApp = () => {
<Route path="/editProfile" element={<EditProfilePage />} />
<Route path="/forums" element={<Forums />} />
<Route path="/directory" element={<Directory />} />
<Route path="/applications" element={<ApplicationsPage />} />
<Route path="/create-application" element={<CreateApplicationPage />} />
<Route path="/update-application/:id" element={<UpdateApplicationPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
Expand Down
4 changes: 4 additions & 0 deletions client/src/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import userReducer from '../features/user/userSlice';
import profilesReducer from '../features/profiles/profilesSlice';
import userProfileReducer from '../features/userProfile/userProfileSlice';
import alumniReducer from '../features/alumni/alumniSlice';
import applicationReducer from '../features/applications/applicationSlice';
import applicationsReducer from '../features/applications/applicationsSlice';

export const store = configureStore({
reducer: {
user: userReducer,
profiles: profilesReducer,
userProfile: userProfileReducer,
alumni: alumniReducer,
application: applicationReducer,
applications: applicationsReducer,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { useAppSelector } from '../../app/hooks';

interface IStatusCount {
status: string;
count: number;
}

const ApplicationDashboard = (): JSX.Element => {
const [totalApplications, setTotalApplications] = useState(0);
const [applicationsByStatus, setApplicationsByStatus] = useState<IStatusCount[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const user = useAppSelector((state) => state.user.userData);

useEffect(() => {
async function fetchAggregatedData() {
setLoading(true);
try {
const response = await axios.get(`/api/applications/aggregated-user-stats/${user?._id}`);
const { totalApplications = 0, applicationsByStatus = [] } = response.data || {};
setTotalApplications(totalApplications);
setApplicationsByStatus(applicationsByStatus);
setLoading(false);
} catch (err) {
const error = err as Error;
console.error('Error fetching aggregated data:', error);
setError(error.message);
setLoading(false);
}
}

fetchAggregatedData();
}, [user?._id]);

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;

return (
<div className="bg-gray-800 p-4 rounded-lg shadow-lg mb-4 w-full max-w-4xl">
<h2 className="font-extrabold text-2xl mb-2">Dashboard</h2>
<table className="min-w-full divide-y divide-gray-700">
<thead>
<tr>
<th className="px-6 py-3 text-center text-xs font-medium text-gray-400 uppercase tracking-wider">
Total Applications
</th>
{applicationsByStatus.map((status) => (
<th
key={status.status}
className="px-6 py-3 text-center text-xs font-medium text-gray-400 uppercase tracking-wider"
>
{status.status}
</th>
))}
</tr>
</thead>
<tbody className="divide-y divide-gray-700">
<tr>
<td className="px-6 py-4 whitespace-nowrap text-sm text-center text-white">
{totalApplications}
</td>
{applicationsByStatus.map((status) => (
<td
key={status.status}
className="px-6 py-4 whitespace-nowrap text-sm text-center text-white"
>
{status.count}
</td>
))}
</tr>
</tbody>
</table>
</div>
);
};

export default ApplicationDashboard;
1 change: 1 addition & 0 deletions client/src/components/Forums/ForumsList/ForumsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const ForumsList = ({ onForumSelect, selectedForumId }: ForumsListProps) => {
return (
<div>
<h2 className="text-xl font-bold mb-4">Forums</h2>

<ul>
<li
onClick={() => onForumSelect(null)}
Expand Down
8 changes: 8 additions & 0 deletions client/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ const Header = () => {
>
Alumni
</Link>
<Link
to="/app/applications"
className={`text-lg md:text-xl ${
currentPath === 'main' ? 'text-gray-300' : 'hover:text-gray-300'
} transition transform hover:scale-105`}
>
Applications
</Link>
<Link
to="/app/profiles"
className={`text-lg md:text-xl ${
Expand Down
89 changes: 89 additions & 0 deletions client/src/features/applications/applicationSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
import { IApplicationFormData, IApplication } from '../../../types/applications';

interface ApplicationState {
application: IApplication | null;
status: 'idle' | 'loading' | 'failed' | 'creating' | 'updating' | 'deleting';
error: string | null;
}

const initialState: ApplicationState = {
application: null,
status: 'idle',
error: null,
};

export const createApplication = createAsyncThunk(
'application/createApplication',
async (applicationData: IApplicationFormData, thunkAPI) => {
try {
const response = await axios.post('/api/applications', applicationData);
return response.data;
} catch (error) {
let errorMessage = 'An error occurred during application creation';
if (axios.isAxiosError(error)) {
errorMessage = error.response?.data || errorMessage;
}
return thunkAPI.rejectWithValue(errorMessage);
}
},
);

export const updateApplication = createAsyncThunk(
'applications/updateApplication',
async ({ id, ...formData }: Partial<IApplicationFormData> & { id: number }, thunkAPI) => {
try {
const response = await axios.put(`/api/applications/${id}`, formData);
return response.data;
} catch (error) {
let errorMessage = 'An error occurred during application update';
if (axios.isAxiosError(error)) {
errorMessage = error.response?.data || errorMessage;
}
return thunkAPI.rejectWithValue(errorMessage);
}
},
);

//TODO Build out delete thunks

const applicationSlice = createSlice({
name: 'application',
initialState,
reducers: {
resetApplicationState(state) {
state.application = null;
state.status = 'idle';
state.error = null;
},
},
extraReducers: (builder) => {
builder
.addCase(createApplication.pending, (state) => {
state.status = 'creating';
})
.addCase(createApplication.fulfilled, (state, action) => {
state.application = action.payload;
state.status = 'idle';
})
.addCase(createApplication.rejected, (state, action) => {
state.status = 'failed';
state.error = action.payload as string;
})
.addCase(updateApplication.pending, (state) => {
state.status = 'updating';
})
.addCase(updateApplication.fulfilled, (state, action) => {
state.application = action.payload;
state.status = 'idle';
})
.addCase(updateApplication.rejected, (state, action) => {
state.status = 'failed';
state.error = action.payload as string;
});
},
});

export const { resetApplicationState } = applicationSlice.actions;
export default applicationSlice.reducer;
53 changes: 53 additions & 0 deletions client/src/features/applications/applicationsSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
import { IApplication } from '../../../types/applications';

interface ApplicationsState {
applications: IApplication[];
status: 'idle' | 'loading' | 'failed';
error: string | null;
}

const initialState: ApplicationsState = {
applications: [],
status: 'idle',
error: null,
};

export const fetchApplications = createAsyncThunk(
'applications/fetchApplications',
async (_, thunkAPI) => {
try {
const response = await axios.get('/api/applications');
return response.data;
} catch (error) {
let errorMessage = 'An error occurred during fetching applications';
if (axios.isAxiosError(error)) {
errorMessage = error.response?.data || errorMessage;
}
return thunkAPI.rejectWithValue(errorMessage);
}
},
);

const applicationsSlice = createSlice({
name: 'applications',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchApplications.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchApplications.fulfilled, (state, action) => {
state.applications = action.payload;
state.status = 'idle';
})
.addCase(fetchApplications.rejected, (state, action) => {
state.status = 'failed';
state.error = action.payload as string;
});
},
});

export default applicationsSlice.reducer;
Loading
Loading