Skip to content
3 changes: 3 additions & 0 deletions backend/src/controllers/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
public questions!: QuestionDTO[];
}

export class ApplicationSettingsDTO implements DTO<ApplicationSettings> {

Check failure on line 74 in backend/src/controllers/dto.ts

View workflow job for this annotation

GitHub Actions / frontend

Class 'ApplicationSettingsDTO' incorrectly implements interface 'DTO<ApplicationSettings>'.
@Type(() => FormSettingsDTO)
@ValidateNested()
@Expose()
Expand All @@ -91,6 +91,9 @@
@IsNumber()
@Expose()
public hoursToConfirm!: number;
Comment thread
sezanzeb marked this conversation as resolved.
}

export class ProjectSettingsDTO implements DTO<ProjectSettings> {

Check failure on line 96 in backend/src/controllers/dto.ts

View workflow job for this annotation

GitHub Actions / frontend

Cannot find name 'ProjectSettings'. Did you mean 'ProjectSettingsDTO'?
@IsBoolean()
@Expose()
public allowRatingProjects!: boolean;
Expand Down Expand Up @@ -153,7 +156,7 @@
public submittedEmail!: EmailTemplateDTO;
}

export class SettingsDTO implements DTO<Omit<Settings, "updatedAt">> {

Check failure on line 159 in backend/src/controllers/dto.ts

View workflow job for this annotation

GitHub Actions / frontend

Class 'SettingsDTO' incorrectly implements interface 'DTO<Omit<Settings, "updatedAt">>'.
@Type(() => ApplicationSettingsDTO)
@ValidateNested()
@Expose()
Expand Down
10 changes: 8 additions & 2 deletions backend/src/entities/application-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
public allowProfileFormUntil!: Date;
@Column()
public hoursToConfirm!: number;
@Column({ default: false })
public allowRatingProjects!: boolean;
@Column()
public fillProfileFormFrom: Date;

Check failure on line 33 in backend/src/entities/application-settings.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'fillProfileFormFrom' has no initializer and is not definitely assigned in the constructor.
@Column()
public fillProfileFormTo: Date;

Check failure on line 35 in backend/src/entities/application-settings.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'fillProfileFormTo' has no initializer and is not definitely assigned in the constructor.
@Column()
public acceptanceDeadline: Date;

Check failure on line 37 in backend/src/entities/application-settings.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'acceptanceDeadline' has no initializer and is not definitely assigned in the constructor.
@Column()
public confirmSpotUntil: Date;

Check failure on line 39 in backend/src/entities/application-settings.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'confirmSpotUntil' has no initializer and is not definitely assigned in the constructor.
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
}
8 changes: 8 additions & 0 deletions backend/src/entities/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ export class EmailSettings {
public forgotPasswordEmail!: EmailTemplate;
}

export class ProjectSettings {
@Column({ default: false })
public allowRatingProjects!: boolean;
}

@Entity()
export class Settings {
@PrimaryGeneratedColumn()
Expand All @@ -64,6 +69,9 @@ export class Settings {
@Type(() => EmailSettings)
@Column(() => EmailSettings)
public email!: EmailSettings;
@Type(() => ProjectSettings)
@Column(() => ProjectSettings)
public rating!: ProjectSettings;
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
}

/**
Expand Down
2 changes: 1 addition & 1 deletion backend/src/services/project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
.map((team) => team.id);

const [settings] = await this._settings.find();
const allowRatingProjects = settings.application.allowRatingProjects;
const allowRatingProjects = settings.project.allowRatingProjects;

Check failure on line 75 in backend/src/services/project-service.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'project' does not exist on type 'Settings'.
Comment thread
sezanzeb marked this conversation as resolved.
const isAdmin = user.role === UserRole.Root;

const projects = await this._projects.find();
Expand Down
4 changes: 2 additions & 2 deletions backend/src/services/rating-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@
}

const settings = await this._settings.getSettings();
if (!settings.application.allowRatingProjects) {
if (!settings.project.allowRatingProjects) {

Check failure on line 239 in backend/src/services/rating-service.ts

View workflow job for this annotation

GitHub Actions / frontend

Property 'project' does not exist on type 'Settings'.
Comment thread
sezanzeb marked this conversation as resolved.
Comment thread
sezanzeb marked this conversation as resolved.
throw new ForbiddenError(
"Rating is not allowed due to application settings",
"Rating is not allowed due to settings",
);
}

Expand Down
10 changes: 9 additions & 1 deletion backend/src/services/settings-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,18 @@
applicationSettings.allowProfileFormFrom = new Date();
applicationSettings.allowProfileFormUntil = new Date();
applicationSettings.hoursToConfirm = 24;
applicationSettings.allowRatingProjects = false;
return applicationSettings;
}

/**
* Creates an application settings object with default values.
*/
private getDefaultProjectSettings(): ProjectSettings {

Check failure on line 124 in backend/src/services/settings-service.ts

View workflow job for this annotation

GitHub Actions / frontend

'getDefaultProjectSettings' is declared but its value is never read.
const projectSettings = new ProjectSettings();
projectSettings.allowRatingProjects = false;
return projectSettings;
}
Comment thread
sezanzeb marked this conversation as resolved.
Comment thread
sezanzeb marked this conversation as resolved.

/**
* Creates a form settings object with default values.
*/
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/pages/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Heading } from "../base/headings";
import { ApplicationSettings } from "../settings/application/application-settings";
import { EmailSettings } from "../settings/mail-settings/email-settings";
import { FrontendSettings } from "../settings/appearance/frontend-settings";
import { ProjectRatingSettings } from "../settings/project-rating/rating-criteria-settings";
import { ProjectProjectSettings } from "../settings/project-rating/rating-criteria-settings";
import { SettingsSaveButton } from "../settings/save-button";
Comment thread
sezanzeb marked this conversation as resolved.
import { Page } from "./page";
import { SimpleCard } from "../base/simple-card";
Expand Down Expand Up @@ -40,7 +40,7 @@ export const Settings = () => (
<EmailSettings />
</SimpleCard>
<SimpleCard>
<ProjectRatingSettings />
<ProjectProjectSettings />
</SimpleCard>
Comment thread
sezanzeb marked this conversation as resolved.
</Page>
);
10 changes: 7 additions & 3 deletions frontend/src/components/pages/status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export const Status = () => {
const { user, updateUser } = useLoginContext();

const confirmationDays = Math.floor(settings.application.hoursToConfirm / 24);
const fillProfileFormFrom = settings.application.fillProfileFormFrom;
const fillProfileFormTo = settings.application.fillProfileFormTo;
const acceptanceDeadline = settings.application.acceptanceDeadline;
const confirmSpotUntil = settings.application.confirmSpotUntil;
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
const isExpired = user == null ? false : isConfirmationExpired(user);
const isNotAttending = isExpired || user?.declined;
const deadline = user?.confirmationExpiresAt;
Comment thread
sezanzeb marked this conversation as resolved.
Expand Down Expand Up @@ -98,7 +102,7 @@ export const Status = () => {
<InternalLink to={Routes.ProfileForm}>
profile form
</InternalLink>
, any time between <b>01.03.2026 - 31.04.2026</b>
, any time between <b>{fillProfileFormFrom} - {fillProfileFormTo}</b>
</Text>
Comment thread
sezanzeb marked this conversation as resolved.
</>
)}
Expand Down Expand Up @@ -145,7 +149,7 @@ export const Status = () => {
<>
<Text style={{ fontSize: "1.15rem" }}>
We will come back to you and send you a acceptance mail until{" "}
<b>01.05.2026</b>.
<b>{acceptanceDeadline}</b>.
</Text>
</>
)}
Expand Down Expand Up @@ -173,7 +177,7 @@ export const Status = () => {
<>
<Text style={{ fontSize: "1.15rem" }}>
If you got accepted, you need to confirm your spot until{" "}
<b>08.05.2026</b>
<b>{confirmSpotUntil}</b>
{user?.admitted && (
<>
{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const CriterionEditor = React.memo(
/**
* A component to edit criteria for rating projects.
*/
export const ProjectRatingSettings = () => {
export const ProjectProjectSettings = () => {
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
// Load all criteria and render them
const [allCriteria, setAllCriteria] = useState<CriterionDTO[]>([]);
const [settings, setSettings] = useState<Partial<SettingsDTO>>({});
Expand All @@ -91,7 +91,7 @@ export const ProjectRatingSettings = () => {

useEffect(() => {
// Only update if settings are loaded
if (settings.application) {
if (settings.rating) {
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
api.updateSettings(settings as SettingsDTO);
}
}, [settings]);
Comment thread
sezanzeb marked this conversation as resolved.
Expand Down Expand Up @@ -138,8 +138,8 @@ export const ProjectRatingSettings = () => {
setSettings((prev) => {
const changedSettings = {
...prev,
application: {
...prev.application,
rating: {
...prev.rating,
allowRatingProjects: value,
},
Comment thread
sezanzeb marked this conversation as resolved.
};
Expand All @@ -155,7 +155,7 @@ export const ProjectRatingSettings = () => {
<FormControlLabel
control={
<Switch
checked={settings?.application?.allowRatingProjects}
checked={settings?.project?.allowRatingProjects}
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
Comment thread
sezanzeb marked this conversation as resolved.
Outdated
onChange={onSwitchChange}
/>
}
Expand Down
Loading