Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
953e03e
Implementing CSV-Import for persons
nobodyzero1 Jul 7, 2025
914dea5
Fix reliability issues reported by SonarQube
nobodyzero1 Jul 7, 2025
4ac06f2
Fix reliability issues reported by SonarQube
nobodyzero1 Jul 8, 2025
e626432
Fix reliability issues reported by SonarQube
nobodyzero1 Jul 8, 2025
1141e9b
Adding changelog
nobodyzero1 Jul 9, 2025
c9fc5ce
Merge branch 'main' into feature/csv-persons-import
nobodyzero1 Jul 9, 2025
144cfb4
Trigger review
nobodyzero1 Jul 9, 2025
abf076b
Trigger review
nobodyzero1 Jul 9, 2025
2f6099e
Minor corrections from code rabbit
nobodyzero1 Jul 9, 2025
a7f6df3
just deleting some comments
nobodyzero1 Jul 9, 2025
d5671cf
correcting general.json
nobodyzero1 Jul 9, 2025
60a2b9e
Merge remote-tracking branch 'origin/main' into feature/csv-persons-i…
nobodyzero1 Aug 1, 2025
d496b97
Merge remote-tracking branch 'origin/main' into feature/csv-persons-i…
nobodyzero1 Sep 2, 2025
bc52747
Continue CSV persons import feature implementation
nobodyzero1 Oct 6, 2025
8628e0e
feat(persons): unify export/import; add group no. and emergency contacts
nobodyzero1 Oct 6, 2025
f35449f
Reducing complexity
nobodyzero1 Oct 9, 2025
07ba6c7
Implement feedback and suggestions for improvement
nobodyzero1 Oct 21, 2025
e6903e9
fixing issues from coderabbitai
nobodyzero1 Oct 21, 2025
af13ea6
fixing further coderabbitai issues
nobodyzero1 Oct 21, 2025
5f619e8
Merge branch 'main' into feature/csv-persons-import
nobodyzero1 Oct 21, 2025
0b48dfa
fixing issues from coderabbitai
nobodyzero1 Oct 22, 2025
bc91edc
fixing issues from coderabbit
nobodyzero1 Oct 23, 2025
b323425
fixing issues from coderabbit
nobodyzero1 Oct 23, 2025
102f567
resolving issue with activating baptized status
nobodyzero1 Oct 23, 2025
aa391ad
fixing coderabbit issues
nobodyzero1 Oct 23, 2025
967762b
allowing null-value for first_report in type-definition bbecause the …
nobodyzero1 Oct 23, 2025
882f8b1
implementing suggestions from coderabbit
nobodyzero1 Oct 23, 2025
e1b95b5
correcting closeOpenHistory according to coderabbit
nobodyzero1 Oct 23, 2025
8efcbaf
Refactor assignment examples logic
nobodyzero1 Oct 23, 2025
73df0c2
resolving examples-issue according to coderabbit
nobodyzero1 Oct 24, 2025
37ebeec
Merge branch 'main' into feature/csv-persons-import
nobodyzero1 Oct 24, 2025
5589bea
Merge branch 'main' into feature/csv-persons-import
nobodyzero1 Nov 11, 2025
c328d7f
feat(ui): Refine link styling and compactify template filling tips
nobodyzero1 Nov 25, 2025
512e71d
updating package for merging
nobodyzero1 Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 142 additions & 137 deletions CHANGELOG.md

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions src/components/icons/IconUpload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { SvgIcon, SxProps, Theme } from '@mui/material';
import { useId } from 'react';

type IconProps = {
color?: string;
width?: number;
height?: number;
sx?: SxProps<Theme>;
className?: string;
};

const IconUpload = ({
color = '#222222',
width = 24,
height = 24,
sx = {},
className,
}: IconProps) => {
const maskId = useId();
return (
<SvgIcon
className={`organized-icon-upload ${className}`}
sx={{ width: `${width}px`, height: `${height}px`, ...sx }}
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<mask
id={maskId}
style={{ maskType: 'alpha' }}
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="24"
height="25"
>
<rect y="0.000488281" width="24" height="24" fill="#D9D9D9" />
</mask>
<g mask={`url(#${maskId})`}>
<path
d="M9 16V10L6.5 12.5L5.4 11.4L12 4.8L18.6 11.4L17.5 12.5L15 10V16H9ZM6 20C5.45 20 4.979 19.804 4.587 19.412C4.195 19.02 3.99934 18.5493 4 18V15H6V18H18V15H20V18C20 18.55 19.804 19.021 19.412 19.413C19.02 19.805 18.5493 20.0007 18 20H6Z"
fill={color}
/>
</g>
</svg>
</SvgIcon>
);
};

export default IconUpload;
1 change: 1 addition & 0 deletions src/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,4 @@ export { default as IconWeek } from './IconWeek';
export { default as IconWine } from './IconWine';
export { default as IconWork } from './IconWork';
export { default as IconYahoo } from './IconYahoo';
export { default as IconUpload } from './IconUpload';
14 changes: 12 additions & 2 deletions src/definition/person.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { AssignmentCode } from './assignment';

export type PrivilegeType = 'elder' | 'ms';
export const ALL_PRIVILEGE_TYPES = ['elder', 'ms'] as const;
export type PrivilegeType = (typeof ALL_PRIVILEGE_TYPES)[number];

export type EnrollmentType = 'AP' | 'FR' | 'FS' | 'FMF';
export const isPrivilegeType = (value: string): value is PrivilegeType => {
return ALL_PRIVILEGE_TYPES.includes(value as PrivilegeType);
};

export const ALL_ENROLLMENT_TYPES = ['AP', 'FR', 'FS', 'FMF'] as const;
export type EnrollmentType = (typeof ALL_ENROLLMENT_TYPES)[number];

export const isEnrollmentType = (value: string): value is EnrollmentType => {
return ALL_ENROLLMENT_TYPES.includes(value as EnrollmentType);
};

export type AssignmentType = {
type: string;
Expand Down
26 changes: 26 additions & 0 deletions src/features/persons/assignments/useAssignments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,31 @@ const useAssignments = () => {
];
}, [t]);

const assignmentLookup = useMemo(() => {
const lookup: Record<string, string> = {};

assignments.forEach((section) => {
const codeHeader = section.header;
section.items.forEach((item) => {
let codeName: string;

if (typeof item.code === 'string') {
codeName = item.code;
} else {
codeName = AssignmentCode[item.code] ?? String(item.code);
}

lookup[codeName] = codeHeader + '.' + item.name;
});
});

return lookup;
}, [assignments]);

const getAssignmentName = (code: string): string => {
return assignmentLookup[code] ?? code;
};

const handleToggleGroup = async (checked: boolean, id: string) => {
const newPerson = structuredClone(person);

Expand Down Expand Up @@ -307,6 +332,7 @@ const useAssignments = () => {
handleToggleGroup,
male,
disqualified,
getAssignmentName,
};
};

Expand Down
82 changes: 82 additions & 0 deletions src/features/persons/import_persons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useRef, useState } from 'react';
import { Box, DialogActions, Stack } from '@mui/material';
import Dialog from '@components/dialog';
import Button from '@components/button';
import usePersonsImport from './useImportPersons';
import { useAppTranslation } from '@hooks/index';
import { IconUpload } from '@components/icons';
import Typography from '@components/typography';

const PersonsImport = () => {
const { t } = useAppTranslation();
const fileInputRef = useRef<HTMLInputElement>(null);
const [isDialogOpen, setIsDialogOpen] = useState(false);

const { handleCsvImport, handleDownloadTemplate } = usePersonsImport();

const handleImportClick = () => {
setIsDialogOpen(true);
};

const handleFileSelect = () => {
setIsDialogOpen(false);
fileInputRef.current?.click();
};

const handleDialogClose = () => {
setIsDialogOpen(false);
};

return (
<Box>
<Button
variant="main"
startIcon={<IconUpload />}
onClick={handleImportClick}
>
{t('tr_import')}
</Button>

<Dialog open={isDialogOpen} onClose={handleDialogClose}>
<Stack spacing="16px">
<Typography className="h2">{t('tr_fileImport')}</Typography>

<Typography
variant="body1"
gutterBottom
sx={{ whiteSpace: 'pre-line' }}
color="var(--grey-400)"
>
{t('tr_csvImportDescription')}
</Typography>

<DialogActions>
<Button variant="secondary" onClick={handleDialogClose}>
{t('tr_cancel')}
</Button>
<Button
variant="main"
onClick={handleDownloadTemplate}
// startIcon={<Download />}
>
{t('tr_templateDownload')}
</Button>
<Button variant="main" onClick={handleFileSelect}>
{t('tr_fileChoose')}
</Button>
</DialogActions>
</Stack>
</Dialog>

<input
type="file"
hidden
ref={fileInputRef}
accept=".csv"
onChange={handleCsvImport}
/>
</Box>
);
};

export default PersonsImport;
Loading