Skip to content

Commit

Permalink
Merge branch 'develop' into frontend-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderVanOyen committed May 22, 2024
2 parents 65f7911 + f47b11f commit 0ba7156
Show file tree
Hide file tree
Showing 25 changed files with 901 additions and 326 deletions.
23 changes: 23 additions & 0 deletions .template.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
DATABASE=postgres
DEBUG=1
DJANGO_ALLOWED_HOSTS='localhost example.com 127.0.0.1 [::1] django'
DJANGO_SUPERUSER_EMAIL=abc@example.com
DJANGO_SUPERUSER_PASSWORD=abc
FRONTEND_URL=http://localhost:3000
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
NEXT_PUBLIC_REDIRECT_URL=/redirect
OAUTH_CLIENT_ID=1234
OAUTH_CLIENT_SECRET=1234
OAUTH_TENANT_ID=1234
REGISTRY_NAME=sel2-1.ugent.be:2002
REGISTRY_PASSWORD=testding
REGISTRY_URL=https://sel2-1.ugent.be:2002
REGISTRY_USER=test
SECRET_KEY=development_key
SQL_DATABASE=pigeonhole_dev
SQL_ENGINE=django.db.backends.postgresql
SQL_HOST=pigeonhole-database
SQL_PASSWORD=password
SQL_PORT=5432
SQL_USER=pigeonhole
SUBMISSIONS_PATH=./backend/uploads/submissions/
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ lint:
docker exec pigeonhole-frontend npm run lint

superuser:


docker exec -it pigeonhole-backend python manage.py createsuperuser

mockdata:
docker exec -it pigeonhole-backend python manage.py runscript mockdata
Expand Down
57 changes: 44 additions & 13 deletions frontend/app/[locale]/admin/users/[id]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
"use client"
import NavBar from "@app/[locale]/components/NavBar";
import Box from "@mui/material/Box";
import initTranslations from "@app/i18n";
import DeleteButton from "@app/[locale]/components/user_components/DeleteButton";
import EditUserForm from "@app/[locale]/components/EditUserForm";
import TranslationsProvider from "@app/[locale]/components/TranslationsProvider";
import React, {useEffect, useState} from "react";
import {getUserData, UserData} from "@lib/api";
import {CircularProgress} from "@mui/material";

async function UserEditPage({params: {locale, id}}: { params: { locale: any, course_id: number } }) {
const {t, resources} = await initTranslations(locale, ["common"])
function UserEditPage({params: {locale, id}}: { params: { locale: any, id: number } }) {
const [resources, setResources] = useState();
const [user, setUser] = useState<UserData | null>(null);
const [userLoading, setUserLoading] = useState(true);

useEffect(() => {
initTranslations(locale, ["common"]).then((result) => {
setResources(result.resources);
})

const fetchUser = async () => {
try {
setUser(await getUserData());
} catch (error) {
console.error("There was an error fetching the user data:", error);
}
}

fetchUser().then(() => setUserLoading(false));
}, [locale])

return (
<TranslationsProvider
Expand All @@ -15,17 +37,26 @@ async function UserEditPage({params: {locale, id}}: { params: { locale: any, cou
namespaces={["common"]}
>
<NavBar/>
<Box
padding={5}
sx={{
display: 'flex',
alignItems: 'space-between',
justifyContent: 'space-between',
}}
>
<EditUserForm userId={id}/>
<DeleteButton userId={id}/>
</Box>
{userLoading ? (
<Box padding={5} sx={{ display: 'flex' }}>
<CircularProgress />
</Box>
) : (
user?.role !== 1 ? (
window.location.href = `/403/`
) : (
<Box
padding={5}
sx={{
display: 'flex',
alignItems: 'space-between',
justifyContent: 'space-between',
}}
>
<EditUserForm userId={id}/>
<DeleteButton userId={id}/>
</Box>
))}
<div id="extramargin" style={{height: "100px"}}></div>
</TranslationsProvider>
);
Expand Down
73 changes: 43 additions & 30 deletions frontend/app/[locale]/admin/users/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
import React from 'react';
"use client";
import React, {useEffect, useState} from 'react';
import initTranslations from "@app/i18n";
import TranslationsProvider from "@app/[locale]/components/TranslationsProvider";
import NavBar from "@app/[locale]/components/NavBar";
import Footer from "@app/[locale]/components/Footer";
import ListView from '@app/[locale]/components/ListView';
import BackButton from '@app/[locale]/components/BackButton';
import EmailIcon from '@mui/icons-material/Email';
import WorkIcon from '@mui/icons-material/Work';
import {fetchUserData, UserData} from "@lib/api";
import UserList from "@app/[locale]/components/admin_components/UserList";
import {Box, CircularProgress} from "@mui/material";

const i18nNamespaces = ['common'];

export default async function Users({ params: { locale } }: { params: { locale: any } }) {
const { t, resources } = await initTranslations(locale, i18nNamespaces);
export default function Users({ params: { locale } }: { params: { locale: any } }) {
const [resources, setResources] = useState();
const [user, setUser] = useState<UserData | null>(null);
const [userLoading, setUserLoading] = useState(true);
const [accessDenied, setAccessDenied] = useState(false);
const [isLoading, setIsLoading] = useState(true);

const headers = [
<React.Fragment key="email"><EmailIcon style={{ fontSize: '20px', verticalAlign: 'middle', marginBottom: '3px' }}/>{" " + t('email')}</React.Fragment>,
,
<React.Fragment key="role"><WorkIcon style={{ fontSize: '20px', verticalAlign: 'middle', marginBottom: '3px' }}/>{" " + t('role')}</React.Fragment>
, ''];
const headers_backend = ['email', 'role', ''];
useEffect(() => {
const initialize = async () => {
try {
const result = await initTranslations(locale, ["common"]);
setResources(result.resources);
const userData = await fetchUserData();
setUser(userData);
if (userData.role !== 1) {
setAccessDenied(true);
window.location.href = `/403/`;
} else {
setAccessDenied(false);
}
} catch (error) {
console.error("There was an error initializing the page:", error);
} finally {
setUserLoading(false);
setIsLoading(false);
}
};

initialize();
}, [locale]);

if (isLoading) {
return (
<Box padding={5} sx={{ display: 'flex' }}>
<CircularProgress />
</Box>
);
}

return (
<TranslationsProvider
Expand All @@ -27,22 +55,7 @@ export default async function Users({ params: { locale } }: { params: { locale:
namespaces={i18nNamespaces}
>
<NavBar />
<div style={{marginTop:60, padding:20}}>
<BackButton
destination={'/home'}
text={t('back_to') + ' ' + t('home') + ' ' + t('page')}
/>
<ListView
admin={true}
headers={headers}
headers_backend={headers_backend}
sortable={[true, false]}
get={'users'}
action_name={'remove'}
action_text={t('remove_user')}
search_text={t('search')}
/>
</div>
{!accessDenied && <UserList />}
</TranslationsProvider>
);
}
47 changes: 28 additions & 19 deletions frontend/app/[locale]/components/AddProjectButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";
import {useTranslation} from "react-i18next";
import {Button, Typography} from "@mui/material";
import {addProject, getUserData, UserData} from "@lib/api";
import {Button, Typography, Skeleton} from "@mui/material";
import {getUserData, UserData} from "@lib/api";
import {useState, useEffect} from "react";

interface EditCourseButtonProps{
Expand All @@ -11,6 +11,7 @@ interface EditCourseButtonProps{
const AddProjectButton = ({course_id}: EditCourseButtonProps) => {
const {t} = useTranslation();
const [user, setUser] = useState<UserData | null>(null);
const [loading, setLoading] = useState(true);


useEffect(() => {
Expand All @@ -22,35 +23,43 @@ const AddProjectButton = ({course_id}: EditCourseButtonProps) => {
}
}

setLoading(false);
fetchUser();
}, [])

return (
loading ?
<Skeleton
variant='rectangular'
width={150}
height={45}
sx={{
borderRadius: '8px'
}}
/> :
<>
{user?.role !== 3 && (
<Button
variant="contained"
color="secondary"
sx={{
width: 'fit-content',
height: 'fit-content',
}}
href={`/course/${course_id}/add_project/`}
>
<Typography
variant="subtitle1"
<Button
variant="contained"
color="secondary"
sx={{
color: 'secondary.contrastText',
display: 'inline-block',
whiteSpace: 'nowrap',
width: 'fit-content',
height: 'fit-content',
}}
href={`/course/${course_id}/add_project/`}
>
<Typography>
<Typography
variant="subtitle1"
sx={{
color: 'secondary.contrastText',
display: 'inline-block',
whiteSpace: 'nowrap',
width: 'fit-content',
}}
>
{t("add_project")}
</Typography>
</Typography>
</Button>
</Button>
)}
</>
)
Expand Down
5 changes: 2 additions & 3 deletions frontend/app/[locale]/components/CourseBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ const CourseBanner = ({course_id}: CourseBannerProps) => {
}
};

fetchCourse();
setLoading(false);
fetchCourse().then(() => setLoading(false));
}, [course_id]);

return (
loading ? (
<Skeleton
variant="rounded"
height={"200px"}
height={"150px"}
sx={{
display: 'flex',
justifyContent: 'center',
Expand Down
Loading

0 comments on commit 0ba7156

Please sign in to comment.