Skip to content

Commit

Permalink
Implement Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-emilius committed Aug 27, 2024
1 parent ec1c2c3 commit 3d451e2
Show file tree
Hide file tree
Showing 49 changed files with 440 additions and 185 deletions.
44 changes: 22 additions & 22 deletions client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,17 @@ const AuthenticatedArea = (props: PropsWithChildren<IAuthenticatedAreaProps>) =>
const [minimizedState, setMinimized] = useLocalStorage<boolean>('navigation_minimized', {
usingJson: true,
})
const [debouncedMinimized] = useDebouncedValue(minimizedState, minimizeAnimationDuration)
const [debouncedMinimized] = useDebouncedValue(
collapseNavigation || minimizedState,
minimizeAnimationDuration,
)
// only use debounced State if value is false because otherwise the text is formatted weirdly if you expand the navigation
const minimized = minimizedState || debouncedMinimized
const minimized = opened ? false : minimizedState || !!debouncedMinimized

const location = useLocation()
const navigationType = useNavigationType()

const showHeader = useIsSmallerBreakpoint('md') || collapseNavigation
const showHeader = useIsSmallerBreakpoint('md')
const auth = useAuthenticationContext()

useEffect(() => {
Expand Down Expand Up @@ -126,9 +129,9 @@ const AuthenticatedArea = (props: PropsWithChildren<IAuthenticatedAreaProps>) =>
<AppShell
header={{ collapsed: !showHeader, height: 60 }}
navbar={{
width: minimizedState ? 70 : 300,
width: collapseNavigation || minimizedState ? 70 : 300,
breakpoint: 'md',
collapsed: { mobile: !opened, desktop: !opened && collapseNavigation },
collapsed: { mobile: !opened, desktop: false },
}}
styles={{
navbar: {
Expand All @@ -139,12 +142,7 @@ const AuthenticatedArea = (props: PropsWithChildren<IAuthenticatedAreaProps>) =>
>
<AppShell.Header>
<Group h='100%' px='md'>
<Burger
opened={opened}
onClick={toggle}
hiddenFrom={collapseNavigation ? undefined : 'md'}
size='md'
/>
<Burger opened={opened} onClick={toggle} hiddenFrom='md' size='md' />
</Group>
</AppShell.Header>

Expand Down Expand Up @@ -204,17 +202,19 @@ const AuthenticatedArea = (props: PropsWithChildren<IAuthenticatedAreaProps>) =>
</Tooltip>
{!minimized && <span>Logout</span>}
</Link>
<Group>
<ActionIcon
visibleFrom='md'
ml='auto'
mr={minimized ? 'auto' : undefined}
variant='transparent'
onClick={() => setMinimized((prev) => !prev)}
>
{minimized ? <CaretDoubleRight /> : <CaretDoubleLeft />}
</ActionIcon>
</Group>
{!collapseNavigation && (
<Group>
<ActionIcon
visibleFrom='md'
ml='auto'
mr={minimized ? 'auto' : undefined}
variant='transparent'
onClick={() => setMinimized((prev) => !prev)}
>
{minimized ? <CaretDoubleRight /> : <CaretDoubleLeft />}
</ActionIcon>
</Group>
)}
</AppShell.Section>
</AppShell.Navbar>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const ApplicationReviewForm = (props: IApplicationReviewFormProps) => {
title: application.topic?.title || application.thesisTitle || '',
comment: application.comment || '',
type:
application.topic?.type || GLOBAL_CONFIG.thesis_types[application.user.studyDegree || '']
application.thesisType || GLOBAL_CONFIG.thesis_types[application.user.studyDegree || '']
? application.user.studyDegree
: null,
advisors: application.topic?.advisors.map((advisor) => advisor.userId) ?? [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { useMemo, useState } from 'react'
import { Button, Space, Stack, Text } from '@mantine/core'
import { Button, Center, Group, Space, Stack, Text } from '@mantine/core'
import { downloadFile } from '../../utils/blob'
import { useApiFile } from '../../hooks/fetcher'
import { Link } from 'react-router-dom'
import { GLOBAL_CONFIG } from '../../config/global'

interface IAuthenticatedIframeProps {
url: string
filename: string
title?: string
height?: number
allowDownload?: boolean
includeLink?: boolean
}

const AuthenticatedFilePreview = (props: IAuthenticatedIframeProps) => {
const { url, filename, allowDownload = true, title, height } = props
const { url, filename, allowDownload = true, includeLink = false, title, height } = props

const [file, setFile] = useState<File>()

Expand All @@ -27,12 +30,23 @@ const AuthenticatedFilePreview = (props: IAuthenticatedIframeProps) => {
{title && <Text ta='center'>{title}</Text>}
<iframe style={{ border: 0 }} height={height} src={iframeUrl} />
{allowDownload && (
<>
<Space mb='md' />
<Button variant='outline' mx='auto' onClick={() => file && downloadFile(file)}>
Download
</Button>
</>
<Center>
<Group mt='md'>
<Button variant='outline' onClick={() => file && downloadFile(file)}>
Download
</Button>
{includeLink && (
<Button
component={Link}
to={`${GLOBAL_CONFIG.server_host}/api${url}`}
variant='outline'
target='_blank'
>
View File
</Button>
)}
</Group>
</Center>
)}
</Stack>
)
Expand Down
1 change: 1 addition & 0 deletions client/src/components/DocumentEditor/DocumentEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const DocumentEditor = (props: IDocumentEditorProps) => {
style={{
minHeight: editMode ? '170px' : undefined,
borderColor: wrapperProps.error ? 'var(--mantine-color-error)' : undefined,
borderStyle: editMode ? 'solid' : 'dashed',
}}
>
{editMode && (
Expand Down
1 change: 1 addition & 0 deletions client/src/components/GanttChart/GanttChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ const GanttChart = (props: IGanttChartProps) => {
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onWheel={handleWheel}
style={{ touchAction: 'none' }}
>
{groups.map((group) => (
<div key={group.groupId} className={classes.groupRow}>
Expand Down
10 changes: 8 additions & 2 deletions client/src/components/TopicData/TopicData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,14 @@ const TopicData = (props: ITopicDataProps) => {
</Grid.Col>
<Grid.Col span={{ md: 3 }}>
<LabeledItem
label='Type'
value={topic.type ? (GLOBAL_CONFIG.thesis_types[topic.type] ?? topic.type) : 'Any'}
label='Thesis Types'
value={
topic.thesisTypes
? topic.thesisTypes.map(
(thesisType) => GLOBAL_CONFIG.thesis_types[thesisType] ?? thesisType,
)
: 'Any'
}
/>
</Grid.Col>
<Grid.Col span={{ md: 3 }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ const PublishedTheses = () => {
<ThesisData thesis={openedThesis} additionalInformation={['abstract']} />
<AuthenticatedFilePreview
url={`/v2/published-theses/${openedThesis.thesisId}/thesis`}
includeLink
height={500}
filename={`${openedThesis.title.replaceAll(' ', '-')}.pdf`}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Title,
TextInput,
Grid,
Card,
} from '@mantine/core'
import { DeclarationOfDataConsent } from '../../components/DeclarationOfDataConsent/DeclarationOfDataConsent'
import LS1Logo from '../../static/ls1logo.png'
Expand All @@ -27,7 +28,6 @@ import UploadArea from '../../components/UploadArea/UploadArea'
import ContentContainer from '../../app/layout/ContentContainer/ContentContainer'
import { AVAILABLE_COUNTRIES } from '../../config/countries'
import { showSimpleError, showSimpleSuccess } from '../../utils/notification'
import { LegacySuccessfulSubmission } from './components/LegacySuccessfulSubmission/LegacySuccessfulSubmission'
import { getApiResponseErrorMessage } from '../../requests/handler'
import DocumentEditor from '../../components/DocumentEditor/DocumentEditor'
import { getHtmlTextLength } from '../../utils/validation'
Expand Down Expand Up @@ -63,6 +63,7 @@ const LegacySubmitApplicationPage = () => {
projects: '',
interests: '',
thesisTitle: '',
thesisType: null,
declarationOfConsentAccepted: false,
examinationReport: undefined,
cv: undefined,
Expand Down Expand Up @@ -118,6 +119,7 @@ const LegacySubmitApplicationPage = () => {
return 'The maximum allowed number of characters is 200.'
}
},
thesisType: isNotEmpty('Please state your thesis type.'),
studyDegree: isNotEmpty('Please state your study degree.'),
studyProgram: isNotEmpty('Please state your study program.'),
enrolledAt: isNotEmpty('Please state your enrollment date.'),
Expand Down Expand Up @@ -150,10 +152,21 @@ const LegacySubmitApplicationPage = () => {
<Box mx='auto' pos='relative'>
<LoadingOverlay visible={loadingOverlayVisible} overlayProps={{ blur: 2 }} />
{applicationSuccessfullySubmitted ? (
<LegacySuccessfulSubmission
title='Your application was successfully submitted!'
text='We will contact you as soon as we have reviewed your application.'
/>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
}}
>
<Card withBorder p='xl'>
<Title order={5}>Your application was successfully submitted!</Title>
<Text c='dimmed'>
We will contact you as soon as we have reviewed your application.
</Text>
</Card>
</div>
) : (
<Stack>
<Center>
Expand Down Expand Up @@ -187,6 +200,7 @@ const LegacySubmitApplicationPage = () => {
interests: values.interests!,
projects: values.projects!,
thesisTitle: values.thesisTitle!,
thesisType: values.thesisType!,
desiredStartDate: values.desiredStartDate!,
}

Expand Down Expand Up @@ -366,20 +380,35 @@ const LegacySubmitApplicationPage = () => {
/>
</Grid.Col>
</Grid>
<Stack gap='0'>
<TextInput
label='Thesis Title Suggestion'
placeholder='Thesis Title Suggestion'
required={true}
{...form.getInputProps('thesisTitle')}
/>
{!form.errors.thesisTitle && (
<Text
fz='xs'
ta='right'
>{`${form.values.thesisTitle?.length ?? 0} / 200`}</Text>
)}
</Stack>
<Grid>
<Grid.Col span={{ md: 8 }}>
<Stack gap='0'>
<TextInput
label='Thesis Title Suggestion'
placeholder='Thesis Title Suggestion'
required={true}
{...form.getInputProps('thesisTitle')}
/>
{!form.errors.thesisTitle && (
<Text
fz='xs'
ta='right'
>{`${form.values.thesisTitle?.length ?? 0} / 200`}</Text>
)}
</Stack>
</Grid.Col>
<Grid.Col span={{ md: 4 }}>
<Select
label='Thesis Type'
required={true}
data={Object.keys(GLOBAL_CONFIG.thesis_types).map((thesisType) => ({
label: GLOBAL_CONFIG.thesis_types[thesisType],
value: thesisType,
}))}
{...form.getInputProps('thesisType')}
/>
</Grid.Col>
</Grid>
<DatePickerInput
leftSection={<Calendar />}
label='Desired Thesis Start Date'
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, Modal, Select, Stack, TextInput } from '@mantine/core'
import { Button, Modal, MultiSelect, Select, Stack, TextInput } from '@mantine/core'
import { ITopic } from '../../../../requests/responses/topic'
import { isNotEmpty, useForm } from '@mantine/form'
import { isNotEmptyUserList } from '../../../../utils/validation'
Expand Down Expand Up @@ -27,14 +27,14 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => {
problemStatement: string
goals: string
references: string
type: string | null
thesisTypes: string[]
supervisorIds: string[]
advisorIds: string[]
}>({
mode: 'controlled',
initialValues: {
title: '',
type: '',
thesisTypes: [],
problemStatement: '',
goals: '',
references: '',
Expand All @@ -56,7 +56,7 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => {
if (opened && topic) {
form.setInitialValues({
title: topic.title,
type: topic.type || '',
thesisTypes: topic.thesisTypes || [],
problemStatement: topic.problemStatement,
goals: topic.goals,
references: topic.references,
Expand All @@ -77,7 +77,7 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => {
requiresAuth: true,
data: {
title: form.values.title,
type: form.values.type || null,
thesisTypes: form.values.thesisTypes.length > 0 ? form.values.thesisTypes : null,
problemStatement: form.values.problemStatement,
goals: form.values.goals,
references: form.values.references,
Expand Down Expand Up @@ -114,17 +114,14 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => {
<form onSubmit={form.onSubmit(onSubmit)}>
<Stack gap='md'>
<TextInput label='Title' required {...form.getInputProps('title')} />
<Select
label='Type'
required
data={[
{ value: '', label: 'Any' },
...Object.entries(GLOBAL_CONFIG.thesis_types).map(([key, value]) => ({
value: key,
label: value,
})),
]}
{...form.getInputProps('type')}
<MultiSelect
label='Thesis Types'
placeholder={form.values.thesisTypes.length > 0 ? undefined : 'All Thesis Types'}
data={Object.entries(GLOBAL_CONFIG.thesis_types).map(([key, value]) => ({
value: key,
label: value,
}))}
{...form.getInputProps('thesisTypes')}
/>
<UserMultiSelect
label='Supervisor'
Expand Down
Loading

0 comments on commit 3d451e2

Please sign in to comment.