From 4ccf40f4442b72f89e3743313c4828b586c41672 Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Tue, 21 Oct 2025 16:50:54 +0200 Subject: [PATCH 1/2] feat: split days --- packages/alexa/src/helpers/report.ts | 5 +- packages/api/schema.gql | 15 ++- packages/api/src/graphql.ts | 21 +++- .../backend/src/resolvers/day.resolver.ts | 8 +- .../backend/src/resolvers/entry.resolver.ts | 6 +- .../backend/src/resolvers/trainee.resolver.ts | 16 ++- packages/backend/src/services/day.service.ts | 2 +- .../backend/src/services/entry.service.ts | 10 +- .../backend/src/services/print.service.ts | 4 +- .../components/src/entry-input-layout.tsx | 1 - packages/components/src/highlighter.tsx | 1 - packages/frontend/src/components/checkbox.tsx | 15 ++- .../frontend/src/components/day-input.tsx | 61 +++++++++- .../src/components/day-status-select.tsx | 34 +++++- .../frontend/src/components/entries-input.tsx | 109 +++++++++++++----- .../frontend/src/components/entry-input.tsx | 78 +++++++++---- .../src/components/text-time-input.tsx | 34 ++++-- packages/frontend/src/graphql/index.tsx | 44 ++++--- .../day-status-select-update-day.gql | 5 +- .../src/graphql/mutations/update-entry.gql | 2 + .../src/graphql/queries/archive-page-data.gql | 2 + .../src/graphql/queries/report-page-data.gql | 3 + .../queries/report-review-page-data.gql | 3 + packages/frontend/src/helper/day-helper.ts | 9 +- packages/frontend/src/pages/archive-page.tsx | 18 ++- .../frontend/src/pages/report-review-page.tsx | 68 ++++++++--- 26 files changed, 432 insertions(+), 142 deletions(-) diff --git a/packages/alexa/src/helpers/report.ts b/packages/alexa/src/helpers/report.ts index 4b424590..8410c593 100644 --- a/packages/alexa/src/helpers/report.ts +++ b/packages/alexa/src/helpers/report.ts @@ -1,9 +1,10 @@ import { Report, Day, Entry } from '@lara/api' import { getLaraConfig } from '../graphql/config' -type ReducedDay = Pick & { entries: Pick[] } +type ReducedDay = Pick & { entries: Pick[] } -const totalDayMinutes = (day: ReducedDay) => day.entries.reduce((acc, entry) => acc + entry.time, 0) +const totalDayMinutes = (day: ReducedDay) => + day.entries.reduce((acc, entry) => acc + (entry.time ? entry.time : entry.time_split!), 0) export const finishedDays = async (days: ReducedDay[]): Promise => { const config = await getLaraConfig() diff --git a/packages/api/schema.gql b/packages/api/schema.gql index 738a33ef..28ceeaa0 100644 --- a/packages/api/schema.gql +++ b/packages/api/schema.gql @@ -46,6 +46,7 @@ type Day implements CommentableInterface { entries: [Entry!]! id: ID! status: DayStatusEnum + status_split: DayStatusEnum } enum DayStatusEnum { @@ -87,13 +88,17 @@ type Entry implements CommentableInterface { createdAt: String! id: ID! orderId: Int! - text: String! - time: Int! + text: String + time: Int + text_split: String + time_split: Int } input EntryInput { - text: String! - time: Int! + text: String + time: Int + text_split: String + time_split: Int } type OAuthPayload { @@ -212,7 +217,7 @@ type Mutation { """ Updates day which is identified by the id argument. """ - updateDay(status: String, id: ID!): Day + updateDay(status: String, status_split: String, id: ID!): Day updateEntry(id: ID!, input: EntryInput!): MutateEntryPayload! updateEntryOrder(entryId: ID!, dayId: ID!, orderId: Int!): MutateEntryPayload! diff --git a/packages/api/src/graphql.ts b/packages/api/src/graphql.ts index 26dfc8a5..29c79f59 100644 --- a/packages/api/src/graphql.ts +++ b/packages/api/src/graphql.ts @@ -93,6 +93,7 @@ export type GqlDay = GqlCommentableInterface & { entries: Array; id: Scalars['ID']['output']; status?: Maybe; + status_split?: Maybe; }; export type GqlDayStatusEnum = @@ -125,13 +126,17 @@ export type GqlEntry = GqlCommentableInterface & { createdAt: Scalars['String']['output']; id: Scalars['ID']['output']; orderId: Scalars['Int']['output']; - text: Scalars['String']['output']; - time: Scalars['Int']['output']; + text?: Maybe; + text_split?: Maybe; + time?: Maybe; + time_split?: Maybe; }; export type GqlEntryInput = { - text: Scalars['String']['input']; - time: Scalars['Int']['input']; + text?: InputMaybe; + text_split?: InputMaybe; + time?: InputMaybe; + time_split?: InputMaybe; }; export type GqlLaraConfig = { @@ -389,6 +394,7 @@ export type GqlMutationUpdateCurrentUserArgs = { export type GqlMutationUpdateDayArgs = { id: Scalars['ID']['input']; status?: InputMaybe; + status_split?: InputMaybe; }; @@ -854,6 +860,7 @@ export type GqlDayResolvers, ParentType, ContextType>; id?: Resolver; status?: Resolver, ParentType, ContextType>; + status_split?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }>; @@ -873,8 +880,10 @@ export type GqlEntryResolvers; id?: Resolver; orderId?: Resolver; - text?: Resolver; - time?: Resolver; + text?: Resolver, ParentType, ContextType>; + text_split?: Resolver, ParentType, ContextType>; + time?: Resolver, ParentType, ContextType>; + time_split?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }>; diff --git a/packages/backend/src/resolvers/day.resolver.ts b/packages/backend/src/resolvers/day.resolver.ts index 5c8705ef..8f10f9ef 100644 --- a/packages/backend/src/resolvers/day.resolver.ts +++ b/packages/backend/src/resolvers/day.resolver.ts @@ -15,7 +15,7 @@ export const dayResolver: GqlResolvers = { export const dayTraineeResolver: GqlResolvers = { Mutation: { - updateDay: async (_parent, { id, status }, { currentUser }) => { + updateDay: async (_parent, { id, status, status_split }, { currentUser }) => { const reports = await reportsWithinApprenticeship(currentUser) const { report, day } = reportDayByDayId(id, reports) @@ -37,15 +37,13 @@ export const dayTraineeResolver: GqlResolvers = { throw new GraphQLError(t('errors.wrongDayStatus')) } - if (!status || !isDayStatus(status) || status === 'holiday') { - throw new GraphQLError(t('errors.wrongDayStatus')) - } + if (status && isDayStatus(status)) day.status = status if (status === 'vacation' || status === 'sick') { day.entries = [] } - day.status = status + if (status_split && isDayStatus(status_split)) day.status_split = status_split await updateReport(report, { updateKeys: ['days'] }) diff --git a/packages/backend/src/resolvers/entry.resolver.ts b/packages/backend/src/resolvers/entry.resolver.ts index 1e27f9bf..fb2aa618 100644 --- a/packages/backend/src/resolvers/entry.resolver.ts +++ b/packages/backend/src/resolvers/entry.resolver.ts @@ -18,7 +18,9 @@ export const entryTraineeResolver: GqlResolvers = { report.days.forEach((day) => { day.entries.forEach((entry) => { const text = entry.text - tmp[text] = tmp[text] ? tmp[text] + 1 : 1 + tmp[text ? text : entry.text_split!] = tmp[text ? text : entry.text_split!] + ? tmp[text ? text : entry.text_split!] + 1 + : 1 }) }) }) @@ -99,6 +101,8 @@ export const entryTraineeResolver: GqlResolvers = { entry.text = input.text entry.time = input.time + entry.text_split = input.text_split + entry.time_split = input.time_split await updateReport(report, { updateKeys: ['days'] }) diff --git a/packages/backend/src/resolvers/trainee.resolver.ts b/packages/backend/src/resolvers/trainee.resolver.ts index 8054d1af..73216458 100644 --- a/packages/backend/src/resolvers/trainee.resolver.ts +++ b/packages/backend/src/resolvers/trainee.resolver.ts @@ -65,13 +65,17 @@ export const traineeTraineeResolver: GqlResolvers = { reports.forEach((report) => { report.days.forEach((day) => { day.entries.forEach((entry) => { - const { text, time } = entry - - if (!textCountsWithTime[text]) { - textCountsWithTime[text] = { count: 0, duration: time, text: text } + const { text, time, text_split, time_split } = entry + + if (!textCountsWithTime[text ? text : text_split!]) { + textCountsWithTime[text ? text : text_split!] = { + count: 0, + duration: time ? time : time_split!, + text: text ? text : text_split!, + } } - textCountsWithTime[text].count += 1 - textCountsWithTime[text].duration = time + textCountsWithTime[text ? text : text_split!].count += 1 + textCountsWithTime[text ? text : text_split!].duration = time ? time : time_split! }) }) }) diff --git a/packages/backend/src/services/day.service.ts b/packages/backend/src/services/day.service.ts index 1f42bf3b..41563788 100644 --- a/packages/backend/src/services/day.service.ts +++ b/packages/backend/src/services/day.service.ts @@ -98,7 +98,7 @@ export const dayMinutes = (day: Day): number => { const status = dayStatus(day) if (status === 'education' || status === 'work') { - return day.entries.reduce((accumulator, entry) => accumulator + entry.time, 0) + return day.entries.reduce((accumulator, entry) => accumulator + (entry.time ? entry.time : entry.time_split!), 0) } else { return 0 } diff --git a/packages/backend/src/services/entry.service.ts b/packages/backend/src/services/entry.service.ts index 44257e89..e71c7c22 100644 --- a/packages/backend/src/services/entry.service.ts +++ b/packages/backend/src/services/entry.service.ts @@ -80,11 +80,17 @@ export const validateEntryUpdate = (report: Report, day: Day, newEntry: Entry, l entries: day.entries.filter((d) => d.id !== newEntry.id), }) - if (day.status === 'work' && minutes + newEntry.time > LaraConfig.maxWorkDayMinutes) { + if ( + day.status === 'work' && + minutes + (newEntry.time ? newEntry.time : newEntry.time_split!) > LaraConfig.maxWorkDayMinutes + ) { throw new GraphQLError(t('errors.dayTimeLimit')) } - if (day.status === 'education' && minutes + newEntry.time > LaraConfig.maxEducationDayMinutes) { + if ( + day.status === 'education' && + minutes + (newEntry.time ? newEntry.time : newEntry.time_split!) > LaraConfig.maxEducationDayMinutes + ) { throw new GraphQLError(t('errors.dayTimeLimit')) } diff --git a/packages/backend/src/services/print.service.ts b/packages/backend/src/services/print.service.ts index c601619d..4f08e4f1 100644 --- a/packages/backend/src/services/print.service.ts +++ b/packages/backend/src/services/print.service.ts @@ -60,8 +60,8 @@ export const createPrintUserData = async (trainee: Trainee): Promise ({ - text: entry.text, - time: entry.time, + text: entry.text ? entry.text : entry.text_split!, + time: entry.time ? entry.time : entry.time_split!, orderId: entry.orderId, }) diff --git a/packages/components/src/entry-input-layout.tsx b/packages/components/src/entry-input-layout.tsx index 203f3a7f..98c53a6d 100644 --- a/packages/components/src/entry-input-layout.tsx +++ b/packages/components/src/entry-input-layout.tsx @@ -199,7 +199,6 @@ export const EntryInputLayout: React.FC = ({ clickHandler, ...rest }) => { - console.log(term) return ( <> diff --git a/packages/components/src/highlighter.tsx b/packages/components/src/highlighter.tsx index 838eb51f..08d3985f 100644 --- a/packages/components/src/highlighter.tsx +++ b/packages/components/src/highlighter.tsx @@ -9,7 +9,6 @@ const Highlighter: React.FC = ({ term, children }) => { } const regex = new RegExp(`(${term})`, 'gi') const parts = children.split(regex) - console.log(parts) return ( <> diff --git a/packages/frontend/src/components/checkbox.tsx b/packages/frontend/src/components/checkbox.tsx index 5ebd58f7..3630b856 100644 --- a/packages/frontend/src/components/checkbox.tsx +++ b/packages/frontend/src/components/checkbox.tsx @@ -5,14 +5,19 @@ import { StyledCheckboxIcon, IconName, StyledCheckBox, StyledCheckBoxInput } fro interface CheckBoxProps { iconName: IconName checked: boolean + disabled: boolean onClick: () => void } -export const CheckBox: React.FunctionComponent = ({ checked, iconName, onClick }) => { +export const CheckBox: React.FunctionComponent = ({ checked, iconName, disabled, onClick }) => { return ( - - - - + <> + {disabled || ( + + + + + )} + ) } diff --git a/packages/frontend/src/components/day-input.tsx b/packages/frontend/src/components/day-input.tsx index 8991bcad..e240a5a4 100644 --- a/packages/frontend/src/components/day-input.tsx +++ b/packages/frontend/src/components/day-input.tsx @@ -10,6 +10,7 @@ import { ReportStatus, useCreateCommentOnDayMutation, useDayInputDataQuery, + useDayStatusSelectUpdateDayMutation, UserInterface, UserTypeEnum, } from '../graphql' @@ -22,6 +23,15 @@ import Loader from './loader' import Total from './total' import { useDayHelper } from '../helper/day-helper' import { useToastContext } from '../hooks/use-toast-context' +import { CheckBox } from './checkbox' +import styled from 'styled-components' + +const SecondaryWrapper = styled.div` + display: flex; + padding: 24px 24px; + justify-content: end; + align-items: center; +` export interface EntryStatusType { message?: string @@ -51,12 +61,12 @@ export const StatusTypes = { } interface DayInputProps { - day?: Pick & { + day: Pick & { comments: (Pick & { user: Pick })[] } & { - entries: (Pick & { + entries: (Pick & { comments: (Pick & { user: Pick })[] @@ -90,6 +100,7 @@ const DayInput: React.FunctionComponent = ({ term, }) => { const { getTotalMinutes } = useDayHelper() + const [mutate] = useDayStatusSelectUpdateDayMutation() const { addToast } = useToastContext() const { loading, data } = useDayInputDataQuery() @@ -101,6 +112,11 @@ const DayInput: React.FunctionComponent = ({ icon: 'Loader', }) + const check_initial = () => day?.entries.reduce((acc, current) => (acc ? true : !!current.text_split), false) + + const initial: boolean = check_initial() === true + + const [halfDays, setHalfDays] = React.useState(initial) const [statusVisible, setStatusVisible] = React.useState(false) const [statusTimeout, setStatusTimeout] = React.useState() @@ -200,6 +216,26 @@ const DayInput: React.FunctionComponent = ({ return null } + const checkBox = () => { + setHalfDays(!halfDays) + const value = !halfDays ? 'work' : 'undefined' + const id = day.id + const status_split = value as DayStatusEnum + void mutate({ + variables: { + id, + status_split, + }, + optimisticResponse: { + updateDay: { + __typename: 'Day', + id, + status_split, + }, + }, + }) + } + const InputHeading = primary ? H1 : H2 return ( @@ -208,7 +244,8 @@ const DayInput: React.FunctionComponent = ({ inputHeader={ <> {getHeading()} - {day && } + + {day && } } statusVisibility={statusVisible} @@ -240,8 +277,26 @@ const DayInput: React.FunctionComponent = ({ reportStatus={reportStatus ?? ReportStatus.Todo} disabled={Boolean(disabled)} trainee={data.currentUser} + secondary={false} updateMessage={updateMessageEntry} /> + {halfDays && ( + <> + + {day && halfDays === true && } + + + + )} ) } diff --git a/packages/frontend/src/components/day-status-select.tsx b/packages/frontend/src/components/day-status-select.tsx index d98a9ef6..609b3e69 100644 --- a/packages/frontend/src/components/day-status-select.tsx +++ b/packages/frontend/src/components/day-status-select.tsx @@ -7,11 +7,12 @@ import strings from '../locales/localization' import { SelectWithIcon } from './select' interface DayStatusSelectProps { - day: Pick + day: Pick disabled?: boolean + secondary: boolean } -const DayStatusSelect: React.FunctionComponent = ({ day, disabled }) => { +const DayStatusSelect: React.FunctionComponent = ({ day, disabled, secondary }) => { const [mutate] = useDayStatusSelectUpdateDayMutation() const getIcon = (): IconName => { @@ -31,28 +32,53 @@ const DayStatusSelect: React.FunctionComponent = ({ day, d return 'Work' } + const getIconSecondary = (): IconName => { + switch (day.status_split) { + case DayStatusEnum.Sick: + return 'Pill' + case DayStatusEnum.Work: + return 'Work' + case DayStatusEnum.Vacation: + return 'Vacation' + case DayStatusEnum.Education: + return 'School' + case DayStatusEnum.Holiday: + return 'Holiday' + } + + return 'Work' + } + const onChange = (event: React.FormEvent) => { const target = event.target as HTMLSelectElement const { value } = target const { id } = day - const status = value as DayStatusEnum + const status = secondary ? undefined : (value as DayStatusEnum) + const status_split = secondary ? (value as DayStatusEnum) : undefined void mutate({ variables: { id, status, + status_split, }, optimisticResponse: { updateDay: { __typename: 'Day', id, status, + status_split, }, }, }) } return ( - + diff --git a/packages/frontend/src/components/entries-input.tsx b/packages/frontend/src/components/entries-input.tsx index 96b8192c..6fdbc26b 100644 --- a/packages/frontend/src/components/entries-input.tsx +++ b/packages/frontend/src/components/entries-input.tsx @@ -30,6 +30,7 @@ interface EntriesInputProps { } trainee: Pick reportStatus: ReportStatus + secondary: boolean disabled: boolean handleStatusChange: (status: EntryStatusType) => void updateMessage?: ( @@ -48,6 +49,7 @@ const EntriesInput: React.FC = ({ disabled, reportStatus, handleStatusChange, + secondary, trainee, updateMessage, term, @@ -63,55 +65,104 @@ const EntriesInput: React.FC = ({ } const createEntry = (entry: EntryInputType) => { - if (!isValidTimeUpdate(day, entry.time)) { + if (!isValidTimeUpdate(day, entry.time ? entry.time : entry.time_split!)) { addToast({ title: strings.errors.error, text: strings.entryStatus.dayLimitError, type: 'error' }) return } handleStatusChange(StatusTypes.loading) - createEntryMutation({ - variables: { - input: { - text: entry.text, - time: entry.time, + if (!secondary) { + createEntryMutation({ + variables: { + input: { + text: entry.text, + time: entry.time, + }, + dayId: day.id, + }, + optimisticResponse: { + createEntry: { + __typename: 'MutateEntryPayload', + day: { + __typename: 'Day', + ...day, + entries: [ + ...day.entries, + { + __typename: 'Entry', + id: 'null', + ...entry, + comments: [], + orderId: day.entries.length, + }, + ], + }, + }, + }, + }) + .then(() => handleStatusChange(StatusTypes.save.success)) + .catch(() => handleStatusChange(StatusTypes.save.error)) + } else { + createEntryMutation({ + variables: { + input: { + text_split: entry.text_split, + time_split: entry.time_split, + }, + dayId: day.id, }, - dayId: day.id, - }, - optimisticResponse: { - createEntry: { - __typename: 'MutateEntryPayload', - day: { - __typename: 'Day', - ...day, - entries: [ - ...day.entries, - { - __typename: 'Entry', - id: 'null', - ...entry, - comments: [], - orderId: day.entries.length, - }, - ], + optimisticResponse: { + createEntry: { + __typename: 'MutateEntryPayload', + day: { + __typename: 'Day', + ...day, + entries: [ + ...day.entries, + { + __typename: 'Entry', + id: 'null', + ...entry, + comments: [], + orderId: day.entries.length, + }, + ], + }, }, }, - }, - }) - .then(() => handleStatusChange(StatusTypes.save.success)) - .catch(() => handleStatusChange(StatusTypes.save.error)) + }) + .then(() => handleStatusChange(StatusTypes.save.success)) + .catch(() => handleStatusChange(StatusTypes.save.error)) + } + } + + const isValidForInput = (entry: Pick) => { + if (secondary) { + if (entry.text) { + return false + } + return true + } else { + if (entry.text) { + return true + } + return false + } } return ( {day.entries .slice() + .filter((entry) => isValidForInput(entry)) .sort((a, b) => a.orderId - b.orderId) .map((entry) => ( = ({ updateMessage={updateMessage ? (msg, commentId) => updateMessage(msg, commentId, entry) : undefined} /> ))} - {!disabled && } + {!disabled && } ) } diff --git a/packages/frontend/src/components/entry-input.tsx b/packages/frontend/src/components/entry-input.tsx index ff1e9111..847f43dd 100644 --- a/packages/frontend/src/components/entry-input.tsx +++ b/packages/frontend/src/components/entry-input.tsx @@ -39,9 +39,9 @@ import { useDayHelper } from '../helper/day-helper' interface EntryDisplayFieldProps { day: Pick & { - entries: Pick[] + entries: Pick[] } - entry: Pick & { + entry: Pick & { comments: (Pick & { user: Pick })[] @@ -49,6 +49,7 @@ interface EntryDisplayFieldProps { trainee: Pick disabled: boolean reportStatus?: ReportStatus + secondary: boolean handleStatusChange?: (status: EntryStatusType) => void showContextMenu?: string setShowContextMenu?: React.Dispatch> @@ -64,6 +65,7 @@ const EntryInput: React.FC = ({ handleStatusChange, trainee, showContextMenu, + secondary, setShowContextMenu, updateMessage, term, @@ -185,7 +187,9 @@ const EntryInput: React.FC = ({ const handleSave = (newEntry: EntryInputType) => { setEditing(false) - if (!isValidTimeUpdate(day, newEntry.time - entry.time)) { + if ( + !isValidTimeUpdate(day, newEntry.time ? newEntry.time - entry.time! : newEntry.time_split! - entry.time_split!) + ) { addToast({ text: strings.entryStatus.changeError, type: 'error' }) return } @@ -195,27 +199,51 @@ const EntryInput: React.FC = ({ } statusChange(StatusTypes.loading) - updateEntryMutation({ - variables: { - id: entry.id, - input: { - text: newEntry.text, - time: newEntry.time, + if (!secondary) { + updateEntryMutation({ + variables: { + id: entry.id, + input: { + text: newEntry.text, + time: newEntry.time, + }, }, - }, - optimisticResponse: { - updateEntry: { - __typename: 'MutateEntryPayload', - entry: { - __typename: 'Entry', - id: entry.id, - ...newEntry, + optimisticResponse: { + updateEntry: { + __typename: 'MutateEntryPayload', + entry: { + __typename: 'Entry', + id: entry.id, + ...newEntry, + }, }, }, - }, - }) - .then(() => statusChange(StatusTypes.change.success)) - .catch(() => statusChange(StatusTypes.change.error)) + }) + .then(() => statusChange(StatusTypes.change.success)) + .catch(() => statusChange(StatusTypes.change.error)) + } else { + updateEntryMutation({ + variables: { + id: entry.id, + input: { + text_split: newEntry.text_split, + time_split: newEntry.time_split, + }, + }, + optimisticResponse: { + updateEntry: { + __typename: 'MutateEntryPayload', + entry: { + __typename: 'Entry', + id: entry.id, + ...newEntry, + }, + }, + }, + }) + .then(() => statusChange(StatusTypes.change.success)) + .catch(() => statusChange(StatusTypes.change.error)) + } } const handleDelete = (e?: React.MouseEvent) => { @@ -300,7 +328,7 @@ const EntryInput: React.FC = ({ return ( <> {editing && !disabled ? ( - + ) : ( = ({ onDragEnter={onDragEnter} onDragEnd={onDragEnd} onDragStart={onDragStart} - text={entry.text} - time={TimeConversion.minutesToString(entry.time)} + text={!secondary ? entry.text! : entry.text_split!} + time={TimeConversion.minutesToString(!secondary ? entry.time! : entry.time_split!)} clickHandler={setEditing} actions={ <> - {!disabled && !isCommentable() && ( + {!disabled && (entry.text || entry.text_split) && !isCommentable() && ( handleDelete()} danger> diff --git a/packages/frontend/src/components/text-time-input.tsx b/packages/frontend/src/components/text-time-input.tsx index 42ec672c..ab4ab4b2 100644 --- a/packages/frontend/src/components/text-time-input.tsx +++ b/packages/frontend/src/components/text-time-input.tsx @@ -13,15 +13,26 @@ interface TextTimeInputProps { onSave: (entry: EntryInput) => void onDelete?: () => void clearOnSave?: boolean - entry?: Pick + entry?: Pick disabled?: boolean autoFocus?: boolean + secondary: boolean } -const TextTimeInput: React.FC = ({ entry, disabled, onDelete, onSave, clearOnSave, autoFocus }) => { +const TextTimeInput: React.FC = ({ + entry, + disabled, + onDelete, + onSave, + clearOnSave, + autoFocus, + secondary, +}) => { const { validateTime } = useValidationHelper() - const [timeInputValue, setTimeInputValue] = useState(entry ? TimeConversion.minutesToString(entry.time) : '') + const [timeInputValue, setTimeInputValue] = useState( + entry ? TimeConversion.minutesToString(!secondary ? entry.time! : entry.time_split!) : '' + ) const timeInput = React.useRef(null) const textInput = React.useRef(null) @@ -99,10 +110,17 @@ const TextTimeInput: React.FC = ({ entry, disabled, onDelete ? TimeConversion.stringToMinutes(timeInput.current.value) : 0 - onSave({ - text: textInput.current.value, - time, - }) + if (!secondary) { + onSave({ + text: textInput.current.value, + time, + }) + } else { + onSave({ + text_split: textInput.current.value, + time_split: time, + }) + } } React.useEffect(() => { @@ -152,7 +170,7 @@ const TextTimeInput: React.FC = ({ entry, disabled, onDelete } } - const textDefaultValue = entry ? entry.text : '' + const textDefaultValue = !secondary ? (entry ? entry.text : '') : entry ? entry.text_split : '' const handleTimeInputChange = (event: React.ChangeEvent) => { const regEx = /^\d{0,2}:?\d{0,2}$/ diff --git a/packages/frontend/src/graphql/index.tsx b/packages/frontend/src/graphql/index.tsx index f3be1f81..b226b619 100644 --- a/packages/frontend/src/graphql/index.tsx +++ b/packages/frontend/src/graphql/index.tsx @@ -91,6 +91,7 @@ export type Day = CommentableInterface & { entries: Array; id: Scalars['ID']['output']; status?: Maybe; + status_split?: Maybe; }; export enum DayStatusEnum { @@ -124,13 +125,17 @@ export type Entry = CommentableInterface & { createdAt: Scalars['String']['output']; id: Scalars['ID']['output']; orderId: Scalars['Int']['output']; - text: Scalars['String']['output']; - time: Scalars['Int']['output']; + text?: Maybe; + text_split?: Maybe; + time?: Maybe; + time_split?: Maybe; }; export type EntryInput = { - text: Scalars['String']['input']; - time: Scalars['Int']['input']; + text?: InputMaybe; + text_split?: InputMaybe; + time?: InputMaybe; + time_split?: InputMaybe; }; export type LaraConfig = { @@ -388,6 +393,7 @@ export type MutationUpdateCurrentUserArgs = { export type MutationUpdateDayArgs = { id: Scalars['ID']['input']; status?: InputMaybe; + status_split?: InputMaybe; }; @@ -712,7 +718,7 @@ export type CreateEntryMutationVariables = Exact<{ }>; -export type CreateEntryMutation = { __typename?: 'Mutation', createEntry: { __typename?: 'MutateEntryPayload', day: { __typename: 'Day', id: string, entries: Array<{ __typename?: 'Entry', id: string, text: string, time: number, orderId: number, comments: Array<{ __typename?: 'Comment', id: string }> }> } } }; +export type CreateEntryMutation = { __typename?: 'Mutation', createEntry: { __typename?: 'MutateEntryPayload', day: { __typename: 'Day', id: string, entries: Array<{ __typename?: 'Entry', id: string, text?: string | undefined, time?: number | undefined, orderId: number, comments: Array<{ __typename?: 'Comment', id: string }> }> } } }; export type CreateOAuthCodeMutationVariables = Exact<{ [key: string]: never; }>; @@ -736,10 +742,11 @@ export type CreateTrainerMutation = { __typename?: 'Mutation', createTrainer?: { export type DayStatusSelectUpdateDayMutationVariables = Exact<{ id: Scalars['ID']['input']; status?: InputMaybe; + status_split?: InputMaybe; }>; -export type DayStatusSelectUpdateDayMutation = { __typename?: 'Mutation', updateDay?: { __typename: 'Day', id: string, status?: DayStatusEnum | undefined } | undefined }; +export type DayStatusSelectUpdateDayMutation = { __typename?: 'Mutation', updateDay?: { __typename: 'Day', id: string, status?: DayStatusEnum | undefined, status_split?: DayStatusEnum | undefined } | undefined }; export type DebugLoginMutationVariables = Exact<{ id: Scalars['String']['input']; @@ -905,7 +912,7 @@ export type UpdateEntryMutationVariables = Exact<{ }>; -export type UpdateEntryMutation = { __typename?: 'Mutation', updateEntry: { __typename?: 'MutateEntryPayload', entry?: { __typename?: 'Entry', id: string, time: number, text: string } | undefined } }; +export type UpdateEntryMutation = { __typename?: 'Mutation', updateEntry: { __typename?: 'MutateEntryPayload', entry?: { __typename?: 'Entry', id: string, time?: number | undefined, text?: string | undefined, time_split?: number | undefined, text_split?: string | undefined } | undefined } }; export type UpdateReportReportReviewPageMutationVariables = Exact<{ id: Scalars['ID']['input']; @@ -966,7 +973,7 @@ export type AlexaLinkingUrlQuery = { __typename?: 'Query', alexaLinkingUrl?: str export type ArchivePageDataQueryVariables = Exact<{ [key: string]: never; }>; -export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, summary?: string | undefined, traineeId: string, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number, text: string }> }> } | undefined> }; +export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, summary?: string | undefined, traineeId: string, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time?: number | undefined, time_split?: number | undefined, text?: string | undefined, text_split?: string | undefined }> }> } | undefined> }; export type AvatarSettingsDataQueryVariables = Exact<{ [key: string]: never; }>; @@ -994,7 +1001,7 @@ export type DashboardPageDataQueryVariables = Exact<{ }>; -export type DashboardPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number }> }> } | undefined>, reportForYearAndWeek?: { __typename?: 'Report', id: string, status: ReportStatus, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, date: string, id: string, entries: Array<{ __typename?: 'Entry', id: string, text: string, time: number, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }>, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> } | undefined }; +export type DashboardPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time?: number | undefined }> }> } | undefined>, reportForYearAndWeek?: { __typename?: 'Report', id: string, status: ReportStatus, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, date: string, id: string, entries: Array<{ __typename?: 'Entry', id: string, text?: string | undefined, time?: number | undefined, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }>, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> } | undefined }; export type DayInputDataQueryVariables = Exact<{ [key: string]: never; }>; @@ -1036,7 +1043,7 @@ export type ReportPageDataQueryVariables = Exact<{ }>; -export type ReportPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', startOfToolUsage?: string | undefined, endOfToolUsage?: string | undefined, id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } | undefined, reportForYearAndWeek?: { __typename?: 'Report', id: string, week: number, year: number, summary?: string | undefined, department?: string | undefined, status: ReportStatus, previousReportLink?: string | undefined, nextReportLink?: string | undefined, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, date: string, id: string, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, entries: Array<{ __typename?: 'Entry', id: string, text: string, time: number, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> }> } | undefined }; +export type ReportPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', startOfToolUsage?: string | undefined, endOfToolUsage?: string | undefined, id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } | undefined, reportForYearAndWeek?: { __typename?: 'Report', id: string, week: number, year: number, summary?: string | undefined, department?: string | undefined, status: ReportStatus, previousReportLink?: string | undefined, nextReportLink?: string | undefined, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, status_split?: DayStatusEnum | undefined, date: string, id: string, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, entries: Array<{ __typename?: 'Entry', id: string, text?: string | undefined, time?: number | undefined, text_split?: string | undefined, time_split?: number | undefined, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> }> } | undefined }; export type ReportReviewPageDataQueryVariables = Exact<{ year: Scalars['Int']['input']; @@ -1045,7 +1052,7 @@ export type ReportReviewPageDataQueryVariables = Exact<{ }>; -export type ReportReviewPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } | undefined, reportForTrainee?: { __typename?: 'Report', id: string, week: number, year: number, summary?: string | undefined, department?: string | undefined, status: ReportStatus, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, date: string, id: string, entries: Array<{ __typename?: 'Entry', id: string, text: string, time: number, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }>, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> } | undefined }; +export type ReportReviewPageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } | undefined, reportForTrainee?: { __typename?: 'Report', id: string, week: number, year: number, summary?: string | undefined, department?: string | undefined, status: ReportStatus, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }>, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, status_split?: DayStatusEnum | undefined, date: string, id: string, entries: Array<{ __typename?: 'Entry', id: string, text?: string | undefined, time?: number | undefined, text_split?: string | undefined, time_split?: number | undefined, orderId: number, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }>, comments: Array<{ __typename?: 'Comment', id: string, text?: string | undefined, published: boolean, user: { __typename?: 'Admin', id: string, firstName: string, lastName: string } | { __typename?: 'Trainee', id: string, firstName: string, lastName: string } | { __typename?: 'Trainer', id: string, firstName: string, lastName: string } }> }> } | undefined }; export type SettingsPageDataQueryVariables = Exact<{ [key: string]: never; }>; @@ -1303,10 +1310,11 @@ export function useCreateTrainerMutation(baseOptions?: Apollo.MutationHookOption } export type CreateTrainerMutationHookResult = ReturnType; export const DayStatusSelectUpdateDayDocument = gql` - mutation DayStatusSelectUpdateDay($id: ID!, $status: String) { - updateDay(id: $id, status: $status) { + mutation DayStatusSelectUpdateDay($id: ID!, $status: String, $status_split: String) { + updateDay(id: $id, status: $status, status_split: $status_split) { id status + status_split __typename } } @@ -1744,6 +1752,8 @@ export const UpdateEntryDocument = gql` id time text + time_split + text_split } } } @@ -1959,7 +1969,9 @@ export const ArchivePageDataDocument = gql` entries { id time + time_split text + text_split } } __typename @@ -2377,6 +2389,7 @@ export const ReportPageDataDocument = gql` } days { status + status_split date id comments { @@ -2393,6 +2406,8 @@ export const ReportPageDataDocument = gql` id text time + text_split + time_split orderId comments { id @@ -2450,12 +2465,15 @@ export const ReportReviewPageDataDocument = gql` } days { status + status_split date id entries { id text time + text_split + time_split orderId comments { id diff --git a/packages/frontend/src/graphql/mutations/day-status-select-update-day.gql b/packages/frontend/src/graphql/mutations/day-status-select-update-day.gql index 381122f4..7c5d3ff9 100644 --- a/packages/frontend/src/graphql/mutations/day-status-select-update-day.gql +++ b/packages/frontend/src/graphql/mutations/day-status-select-update-day.gql @@ -1,7 +1,8 @@ -mutation DayStatusSelectUpdateDay($id: ID!, $status: String) { - updateDay(id: $id, status: $status) { +mutation DayStatusSelectUpdateDay($id: ID!, $status: String, $status_split: String) { + updateDay(id: $id, status: $status, status_split: $status_split) { id status + status_split __typename } } diff --git a/packages/frontend/src/graphql/mutations/update-entry.gql b/packages/frontend/src/graphql/mutations/update-entry.gql index 31c967ab..4cd1a90f 100644 --- a/packages/frontend/src/graphql/mutations/update-entry.gql +++ b/packages/frontend/src/graphql/mutations/update-entry.gql @@ -4,6 +4,8 @@ mutation updateEntry($id: ID!, $input: EntryInput!) { id time text + time_split + text_split } } } diff --git a/packages/frontend/src/graphql/queries/archive-page-data.gql b/packages/frontend/src/graphql/queries/archive-page-data.gql index 25c8a3c4..0b76c24d 100644 --- a/packages/frontend/src/graphql/queries/archive-page-data.gql +++ b/packages/frontend/src/graphql/queries/archive-page-data.gql @@ -19,7 +19,9 @@ query ArchivePageData { entries { id time + time_split text + text_split } } __typename diff --git a/packages/frontend/src/graphql/queries/report-page-data.gql b/packages/frontend/src/graphql/queries/report-page-data.gql index 8ac3dfb4..6f95d5d3 100644 --- a/packages/frontend/src/graphql/queries/report-page-data.gql +++ b/packages/frontend/src/graphql/queries/report-page-data.gql @@ -29,6 +29,7 @@ query ReportPageData($year: Int!, $week: Int!) { } days { status + status_split date id comments { @@ -45,6 +46,8 @@ query ReportPageData($year: Int!, $week: Int!) { id text time + text_split + time_split orderId comments { id diff --git a/packages/frontend/src/graphql/queries/report-review-page-data.gql b/packages/frontend/src/graphql/queries/report-review-page-data.gql index 5b2f2dfe..91ed3e43 100644 --- a/packages/frontend/src/graphql/queries/report-review-page-data.gql +++ b/packages/frontend/src/graphql/queries/report-review-page-data.gql @@ -23,12 +23,15 @@ query reportReviewPageData($year: Int!, $week: Int!, $trainee: ID!) { } days { status + status_split date id entries { id text time + text_split + time_split orderId comments { id diff --git a/packages/frontend/src/helper/day-helper.ts b/packages/frontend/src/helper/day-helper.ts index 0fa9a1f5..565f528a 100644 --- a/packages/frontend/src/helper/day-helper.ts +++ b/packages/frontend/src/helper/day-helper.ts @@ -1,8 +1,11 @@ import { Day, DayStatusEnum, Entry, useConfigQuery } from '../graphql' type UseDayHelper = { - isValidTimeUpdate: (day: Pick & { entries: Pick[] }, newTime: number) => boolean - getTotalMinutes: (day: Pick & { entries: Pick[] }) => number + isValidTimeUpdate: ( + day: Pick & { entries: Pick[] }, + newTime: number + ) => boolean + getTotalMinutes: (day: Pick & { entries: Pick[] }) => number } export const useDayHelper = (): UseDayHelper => { @@ -29,7 +32,7 @@ export const useDayHelper = (): UseDayHelper => { const getTotalMinutes: UseDayHelper['getTotalMinutes'] = (day) => { if (day.status === DayStatusEnum.Education || day.status === DayStatusEnum.Work) { - return day.entries.reduce((accumulator, entry) => accumulator + entry.time, 0) + return day.entries.reduce((accumulator, entry) => accumulator + (entry.time ? entry.time : entry.time_split!), 0) } else { return 0 } diff --git a/packages/frontend/src/pages/archive-page.tsx b/packages/frontend/src/pages/archive-page.tsx index 1357706c..88abe5cd 100644 --- a/packages/frontend/src/pages/archive-page.tsx +++ b/packages/frontend/src/pages/archive-page.tsx @@ -75,8 +75,10 @@ const searchFilter = entries: { __typename?: 'Entry' | undefined id: string - time: number - text: string + time?: number | undefined + text?: string | undefined + text_split?: string | undefined + time_split?: number | undefined }[] }[] } @@ -97,7 +99,9 @@ const searchFilter = let textMatch = true if (searchText) { textMatch = report.days.some((day) => - day.entries.some((entry) => entry.text.toLowerCase().includes(searchText.toLowerCase())) + day.entries.some((entry) => + (entry.text ? entry.text : entry.text_split!).toLowerCase().includes(searchText.toLowerCase()) + ) ) if (!textMatch && report.summary) { textMatch = report.summary.toLowerCase().includes(searchText.toLowerCase()) @@ -322,7 +326,12 @@ const ArchivePage: React.FunctionComponent = () => { {filteredReports.length !== 0 && ( - + {strings.archivePage.tableHead.calendarWeek} @@ -357,6 +366,7 @@ const ArchivePage: React.FunctionComponent = () => { checkBoxUpdate(report.id, !getCheckState(report.id))} /> diff --git a/packages/frontend/src/pages/report-review-page.tsx b/packages/frontend/src/pages/report-review-page.tsx index ac2ad1cd..6c6a1827 100644 --- a/packages/frontend/src/pages/report-review-page.tsx +++ b/packages/frontend/src/pages/report-review-page.tsx @@ -47,6 +47,14 @@ import strings from '../locales/localization' import { useToastContext } from '../hooks/use-toast-context' import { Template } from '../templates/template' import { useDayHelper } from '../helper/day-helper' +import { styled } from 'styled-components' + +const SecondaryWrapper = styled.div` + display: flex; + padding: 24px 24px; + justify-content: end; + align-items: center; +` interface ReportReviewPageState { showApproveConfimationModal: boolean @@ -380,24 +388,56 @@ const ReportReviewPage: React.FunctionComponent = () => {

{getHeading(day)}

- + - {day.status === 'work' || day.status === 'education' ? ( + {(day.status && day.status === 'work') || day.status === 'education' ? ( + <> + {day.entries + .filter((entry) => entry.text !== null) + .map((entry, entryIndex) => ( + updateEntryComment(entry, msg, commentId)} + /> + ))} + {!day.status_split && ( + + + + )} + + ) : null} + {(day.status_split && day.status_split === 'work') || day.status_split === 'education' ? ( <> - {day.entries.map((entry, entryIndex) => ( - updateEntryComment(entry, msg, commentId)} - /> - ))} + + + + + + {day.entries + .filter((entry) => entry.text_split !== null) + .map((entry, entryIndex) => ( + updateEntryComment(entry, msg, commentId)} + /> + ))} From 78464c4e771c9e425c1aa87f2b2c15b7e4e82f4f Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Wed, 22 Oct 2025 09:06:29 +0200 Subject: [PATCH 2/2] chore: format --- packages/frontend/src/pages/dashboard-page.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/frontend/src/pages/dashboard-page.tsx b/packages/frontend/src/pages/dashboard-page.tsx index 2394ed52..532dae24 100644 --- a/packages/frontend/src/pages/dashboard-page.tsx +++ b/packages/frontend/src/pages/dashboard-page.tsx @@ -61,14 +61,16 @@ const DashboardPage: React.FunctionComponent = () => { <> {showDayInput && ( - + {day && ( + + )} )}