Skip to content

Commit

Permalink
Feat/authentication (#21)
Browse files Browse the repository at this point in the history
* fixed gitignore

* added docker

* half done

* Filter by userId

* single period, dynamic reporting periods

* added jwt on frontend

---------

Co-authored-by: Bujdosó Gergő <bujgergo@gmail.com>
  • Loading branch information
IvnDmnks and FearsomeRover authored Nov 22, 2024
1 parent 0fe86ec commit ab91919
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 42 deletions.
1 change: 1 addition & 0 deletions apps/backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ JWT_EXPIRATION="1d"
AUTHSCH_CLIENT_ID=""
AUTHSCH_CLIENT_SECRET=""
BACKEND_PORT=3001
FRONTEND_AUTHORIZED_URL="http://localhost:3000/auth/callback"
3 changes: 1 addition & 2 deletions apps/backend/src/tasks/entities/task.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ export class Tasks {
@IsInt()
sprintId: number;

@IsInt()
userId: number;
userId: string;

@IsInt()
projectId: number;
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/.env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
BACKEND_URL= https://localhost:3001
NEXT_PUBLIC_BACKEND_URL= http://localhost:3001
9 changes: 9 additions & 0 deletions apps/frontend/src/app/(with-layout)/adminoverview/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import AdminOverview from '../../../components/AdminOverview';

export default function Home() {
return (
<main className='flex-1 items-center justify-center bg-page-bg-color'>
<AdminOverview />
</main>
);
}
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(with-layout)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Footer } from '../../components/Footer';
import { Footer } from '../../components/footer';
import Navbar from '../../components/Navbar';
import Section from '../../components/section';

Expand Down
9 changes: 9 additions & 0 deletions apps/frontend/src/app/(with-layout)/singleperiod/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SinglePeriod from '../../../components/SinglePeriod';

export default function Home() {
return (
<main className='flex items-center justify-center bg-page-bg-color'>
<SinglePeriod />
</main>
);
}
16 changes: 16 additions & 0 deletions apps/frontend/src/app/auth/callback/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';

export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
const jwt = request.nextUrl.searchParams.get('jwt');

if (!jwt) {
return new Response('Unauthorized', { status: 401 });
}

cookies().set('jwt', jwt, { path: '/' });

return NextResponse.redirect(new URL('/profile', request.url));
}
10 changes: 10 additions & 0 deletions apps/frontend/src/app/auth/logout/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';

export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
cookies().delete('jwt');

return NextResponse.redirect(new URL('/', request.url));
}
115 changes: 115 additions & 0 deletions apps/frontend/src/components/AdminOverview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
'use client';

import { useEffect, useState } from 'react';

import api from '../lib/axiosConfig';

export default function AdminOverview() {
interface Task {
id: number;
description: string;
createdAt: string;
projectId: number;
userId: string;
}

const [tasks, setTasks] = useState<Task[]>([]);
const [sort, setSort] = useState<Task[]>([]);
const [filter, setFilter] = useState<string>('');
const [selectedUserId, setSelectedUserId] = useState<string>('');

console.log(sort);

useEffect(() => {
api.get('/tasks').then((res) => {
setTasks(res.data);
setSort(res.data);
console.log(res.data);
});
}, []);

useEffect(() => {
let filteredTasks = [...tasks];

if (filter === 'name') {
setSort([...tasks].sort((a, b) => a.userId.localeCompare(b.userId)));
} else if (filter === 'date') {
setSort([...tasks].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()));
} else if (filter === 'project') {
setSort([...tasks].sort((a, b) => a.projectId - b.projectId));
} else {
setSort(tasks);
}

if (selectedUserId) {
filteredTasks = filteredTasks.filter((task) => task.userId === selectedUserId);
}
setSort(filteredTasks);
}, [filter, tasks, selectedUserId]);

const uniqueUserIds = Array.from(new Set(tasks.map((task) => task.userId)));
return (
<div className='w-3/5 flex px-8 py-8 mx-auto lg:py-0'>
<div className='p-6 space-y-4 md:space-y-6 sm:p-8 w-full'>
<h1 className='text-xl font-bold leading-tight tracking-tight text-text-color-h1 md:text-4xl dark:text-bg-color2 w-full text-center'>
Áttekintés
</h1>
<div>
<select
id='filter'
value={filter}
onChange={(e) => setFilter(e.target.value)}
className='rounded bg-page-bg-color text-text-color dark:bg-bg-color2'
>
<option value='' className='text-text-color hover:bg-bg-color2 hover:text-text-color'>
Rendezés
</option>
<option value='name' className='text-text-color hover:bg-bg-color2 hover:text-text-color'>
Tagok szerint
</option>
<option value='tasks' className='text-text-color hover:bg-bg-color2 hover:text-text-color'>
Projekt szerint
</option>
<option value='date' className='text-text-color hover:bg-bg-color2 hover:text-text-color'>
Időszak szerint
</option>
</select>
<select
id='filter'
value={filter}
onChange={(e) => setSelectedUserId(e.target.value)}
className='rounded ml-4 bg-page-bg-color text-text-color dark:bg-bg-color2'
>
{uniqueUserIds.map((userId) => (
<option key={userId} value={userId}>
{userId}
</option>
))}
</select>
</div>
<div>
<table className='min-w-full max-w-lg text-center text-sm font-light text-surface dark:text-white'>
<thead className='border-b border-neutral-200 font-medium dark:border-white/10 text-2xl'>
<tr>
<th className='text-text-color'>Név</th>
<th className='text-text-color'>Projekt</th>
<th className='text-text-color'>Időszak</th>
<th className='text-text-color'>Leírás</th>
</tr>
</thead>
<tbody>
{sort.map((task) => (
<tr key={task.id}>
<td className='text-text-color font-semibold'>{task.userId}</td>
<td className='text-text-color font-semibold'>{task.projectId}</td>
<td className='text-text-color font-semibold'>{task.createdAt}</td>
<td className='text-text-color font-semibold'>{task.description}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
6 changes: 3 additions & 3 deletions apps/frontend/src/components/AfterLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function GreetingsPage() {
<div className='flex flex-row gap-x-4 items-center justify-center'>
<a
href='/reportingperiod'
className='block w-64 h-96 max-w-sm py-6 px-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700'
className='block w-64 h-96 max-w-sm py-6 px-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 transition duration-300'
>
<h5 className='mb-2 text-2xl font-bold tracking-tight text-text-color dark:text-white'>
Beszámolási időszakok
Expand All @@ -30,7 +30,7 @@ export default function GreetingsPage() {
</a>
<a
href='/currentjobs'
className='block w-64 h-96 max-w-sm p-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700'
className='block w-64 h-96 max-w-sm p-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 transition duration-300'
>
<h5 className='mb-2 text-2xl font-bold tracking-tight text-text-color dark:text-white'>Munkák</h5>
<p className='font-normal text-text-color dark:text-gray-400'>Láthatod a jelenleg zajló</p>
Expand All @@ -46,7 +46,7 @@ export default function GreetingsPage() {
</a>
<a
href='/newproject'
className='block w-64 h-96 max-w-sm p-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700'
className='block w-64 h-96 max-w-sm p-6 bg-bg-color2 border border-black rounded-lg shadow hover:bg-bg-color1 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 transition duration-300'
>
<h5 className='mb-2 text-2xl font-bold tracking-tight text-text-color dark:text-white'>Új Projekt</h5>
<p className='font-normal text-text-color dark:text-gray-400'>Itt tudsz új projeket nyitni.</p>
Expand Down
10 changes: 5 additions & 5 deletions apps/frontend/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
export default function Navbar() {
return (
<header className='flex flex-col items-center justify-between px-8 py-5 bg-page-bg-color'>
<header className='flex flex-col items-center justify-between px-8 py-5 bg-page-bg-color sticky top-0'>
<nav className='text-text-color space-x-5 rounded py-5'>
<a
href='/afterlogin'
className='w-32 h-32 hover:scale-110 transform transition-transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg duration-300'
className='w-32 h-32 hover:scale-110 transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg transition duration-300'
>
Kezdőlap
</a>
<a
href='/reportingperiod'
className='w-32 h-32 hover:scale-110 transform transition-transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg duration-300'
className='w-32 h-32 hover:scale-110 transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg transition duration-300'
>
Beszámoló időszakok
</a>
<a
href='/currentjobs'
className='w-32 h-32 hover:scale-110 transform transition-transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg duration-300'
className='w-32 h-32 hover:scale-110 transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg transition duration-300'
>
Munkák
</a>
<a
href='/newproject'
className='w-32 h-32 hover:scale-110 transform transition-transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg duration-300'
className='w-32 h-32 hover:scale-110 transform hover:bg-bg-color1 font-bold py-2 px-4 rounded-lg hover:shadow-lg transition duration-300'
>
Új Projekt
</a>
Expand Down
5 changes: 2 additions & 3 deletions apps/frontend/src/components/NewProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default function NewProject() {

const handleChange = (event: { target: { name: any; value: any } }) => {
setFormData({ ...formData, [event.target.name]: event.target.value });
console.log('asda');
};

const projectFormState = async (event: FormEvent<HTMLFormElement>) => {
Expand All @@ -31,7 +30,7 @@ export default function NewProject() {
data: JSON.stringify(formData),
});
} catch (error) {
console.log((error as any).message);
setErrorMessage((error as any).message);
}
};

Expand Down Expand Up @@ -66,7 +65,7 @@ export default function NewProject() {
<div className='justify-center flex'>
<button
type='submit'
className='w-1/2 border font-semibold text-text-color rounded-lg text-sm px-5 py-2.5 text-center border-[#8b97a4] hover:border-text-color hover:bg-[#2c3540] focus:ring-4 '
className='w-1/2 border font-semibold text-text-color rounded-lg text-sm px-5 py-2.5 text-center border-[#8b97a4] hover:border-text-color hover:bg-[#2c3540] focus:ring-4 transition duration-300'
>
Létrehozás
</button>
Expand Down
81 changes: 56 additions & 25 deletions apps/frontend/src/components/ReportingPeriod.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
'use client';

import { useEffect, useState } from 'react';

export function ReportingPeriod() {
interface Week {
start: string;
end: string;
numberOfTheWeek: number;
completed?: boolean;
}

const [weeks, setWeeks] = useState<Week[]>([]);

useEffect(() => {
const generateWeeks = (startDate: Date, weeksCounter: number): Week[] => {
const weeks: Week[] = [];
const current = new Date(startDate);

for (let i = 0; i < weeksCounter; ++i) {
const start = new Date(current);
start.setDate(current.getDate() - current.getDay() + 1);
const end = new Date(start);
end.setDate(start.getDate() + 6);

weeks.push({
start: start.toLocaleDateString(),
end: end.toLocaleDateString(),
numberOfTheWeek: i + 1,
});

current.setDate(current.getDate() + 7);
}

return weeks;
};

const startDate = new Date('2024-09-02'); //Itt át lehet állítani félévenként esetleg vagy valami okosabb megoldást kitalálni.
const generatedWeeks = generateWeeks(startDate, 14);
setWeeks(generatedWeeks);
}, []);

return (
<div className='flex flex-col w-1/2'>
<div className='text-center pt-8'>
Expand All @@ -15,35 +56,25 @@ export function ReportingPeriod() {
</tr>
</thead>
<tbody>
<tr className='border-b border-neutral-200 transition duration-300 ease-in-out hover:bg-bg-color1 dark:border-white/10 dark:hover:bg-neutral-600'>
<td className='float-left whitespace-nowrap px-6 py-4 font-medium tracking-wider'>
<a href='#'>2021.01.01 - 2021.01.15</a>
</td>
<td className='float-right whitespace-nowrap px-6 py-4 font-medium'>Pipa vagy x</td>
</tr>
<tr className='border-b border-neutral-200 transition duration-300 ease-in-out hover:bg-bg-color1 dark:border-white/10 dark:hover:bg-neutral-600'>
<td className='float-left whitespace-nowrap px-6 py-4 font-medium tracking-wider'>
<a href='#'>2021.01.16 - 2021.02.01.</a>
</td>
<td className='float-right whitespace-nowrap px-6 py-4 font-medium'>Pipa vagy x</td>
</tr>
<tr className='border-b border-neutral-200 transition duration-300 ease-in-out hover:bg-bg-color1 dark:border-white/10 dark:hover:bg-neutral-600'>
<td className='float-left whitespace-nowrap px-6 py-4 font-medium tracking-wider'>
<a href='#'>2021.02.02. - 2021.02.15.</a>
</td>
<td className='float-right whitespace-nowrap px-6 py-4 font-medium'>Pipa vagy x</td>
</tr>
<tr className='border-b border-neutral-200 transition duration-300 ease-in-out hover:bg-bg-color1 dark:border-white/10 dark:hover:bg-neutral-600'>
<td className='float-left whitespace-nowrap px-6 py-4 font-medium tracking-wider'>
<a href='#'>2021.02.15. - 2021.03.01.</a>
</td>
<td className='float-right whitespace-nowrap px-6 py-4 font-medium'>Pipa vagy x</td>
</tr>
{weeks.map((week) => (
<tr
key={`${week.start}-${week.end}`}
className='border-b border-neutral-200 transition duration-300 ease-in-out hover:bg-bg-color1 dark:border-white/10 dark:hover:bg-neutral-600'
>
<a
href={`/singleperiod?numberOfTheWeek=${encodeURIComponent(week.numberOfTheWeek)}&start=${encodeURIComponent(week.start)}&end=${encodeURIComponent(week.end)}`}
>
<td className='float-left whitespace-nowrap px-6 py-4 font-medium tracking-wider'>
{week.numberOfTheWeek}. hét ({week.start} - {week.end})
</td>
</a>
<td className='float-right whitespace-nowrap px-6 py-4 font-medium'>Pipa vagy x</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
<a href='https://github.com/kir-dev/sprint-review-app' target='_blank' rel='noreferrer' />
</div>
);
}
Loading

0 comments on commit ab91919

Please sign in to comment.