Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8d71b4c
disable product action if expired for sponsor
ateamcms Feb 12, 2026
3f045a2
fix fund query filter in view all products on voucher page
ateamcms Feb 12, 2026
36cf0ec
show duplicates by csv primary key when upload prevalidation batch
ateamcms Feb 13, 2026
6662ffd
Bump qs in the npm_and_yarn group across 1 directory
dependabot[bot] Feb 14, 2026
9c90dd7
add Label component on webshop and dashboards and cleanup unused labe…
dev-rminds Feb 17, 2026
ba597e1
show primary key duplicates within prevalidations csv - minor refacto…
dev-rminds Feb 17, 2026
61fd3ff
Merge branch 'consistency.labels' into feature.disable-product-action…
dev-rminds Feb 17, 2026
f44fa16
fix merge issue
dev-rminds Feb 17, 2026
bbc0139
add type button to edit product button
dev-rminds Feb 17, 2026
429876b
media type validation in dashboard
ateamcms Feb 17, 2026
cbf53f9
fix reimbursement page title translation
ateamcms Feb 18, 2026
e5692e5
reload employees list after employee update
ateamcms Feb 18, 2026
211e005
update dashboard image uploaders formats list, fix cropper output for…
dev-rminds Feb 19, 2026
a7ee39c
minor refactoring and fix fetch filters on employee delete
dev-rminds Feb 19, 2026
fb20d8f
Merge pull request #967 from teamforus/feature.disable-product-action…
RobinMeles Feb 19, 2026
7c487e0
replace brp record type partner gender female with partner and childr…
ateamcms Feb 23, 2026
afdd324
fix pagination in provider funds table
ateamcms Feb 23, 2026
0ba89c1
remove loading text when loading page
ateamcms Feb 23, 2026
caa5278
minor refactoring, replace old useFilter usage on webshop physical ca…
dev-rminds Feb 23, 2026
0bd3bb8
remove deprecated useFilter hook
dev-rminds Feb 23, 2026
cee073c
Merge pull request #971 from teamforus/consistency.labels
RobinMeles Feb 24, 2026
4f6ac7d
Merge branch 'develop' into feature.replace-brp-record-type-partner-g…
RobinMeles Feb 24, 2026
d6bfda9
Merge pull request #977 from teamforus/feature.remove-loading-text-wh…
RobinMeles Feb 24, 2026
2ea69c4
Merge branch 'develop' into fixes.reload-employees-list-after-employe…
RobinMeles Feb 24, 2026
225c46e
translation in push notification
RobinMeles Feb 24, 2026
6cacf1a
Merge pull request #974 from teamforus/fixes.reload-employees-list-af…
RobinMeles Feb 24, 2026
d8f581b
Merge branch 'develop' into feature.replace-brp-record-type-partner-g…
RobinMeles Feb 24, 2026
f69b39b
Merge branch 'develop' into fixes.pagination-in-provider-funds-table
RobinMeles Feb 24, 2026
e2edf6b
Merge pull request #976 from teamforus/fixes.pagination-in-provider-f…
RobinMeles Feb 24, 2026
27a707f
Merge pull request #973 from teamforus/fixes.reimbursement-page-title…
RobinMeles Feb 24, 2026
3e856a6
Merge branch 'develop' into fixes.fund-query-filter-in-view-all-produ…
RobinMeles Feb 24, 2026
89cc35b
Merge pull request #968 from teamforus/fixes.fund-query-filter-in-vie…
RobinMeles Feb 24, 2026
7510864
Merge pull request #975 from teamforus/feature.replace-brp-record-typ…
RobinMeles Feb 24, 2026
a581213
Merge branch 'develop' into feature.show-duplicates-by-csv-primary-ke…
RobinMeles Feb 24, 2026
493696d
Merge pull request #969 from teamforus/feature.show-duplicates-by-csv…
RobinMeles Feb 24, 2026
ed0c9ce
Merge branch 'develop' into feature.media-type-validation-in-dashboard
RobinMeles Feb 25, 2026
7fd8edb
Merge pull request #972 from teamforus/feature.media-type-validation-…
RobinMeles Feb 25, 2026
3c9ac37
Merge branch 'develop' into dependabot/npm_and_yarn/npm_and_yarn-14dc…
RobinMeles Feb 25, 2026
60b075b
Merge pull request #970 from teamforus/dependabot/npm_and_yarn/npm_an…
RobinMeles Feb 25, 2026
6c96408
Merge pull request #978 from teamforus/develop
RobinMeles Feb 25, 2026
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module.exports = {
plugins: ['no-for-of-loops', 'no-function-declare-after-return', 'react', 'react-hooks', 'prettier'],
rules: {
// ...
// 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies
'react/react-in-jsx-scope': 'off',
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,6 @@ img {
transition: color 0.3s;
}

.transition-background {
transition: background-color 0.3s;
}

.text-black {
color: #000000;
}
Expand Down Expand Up @@ -1579,4 +1575,4 @@ img {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,8 @@
}
}

.label {
&:not(:last-child):not(:last-of-type) {
margin: 0;
}

.label-text {
display: inline-block;
}
.label:not(:last-child):not(:last-of-type) {
margin: 0;
}

&:last-child {
Expand Down
10 changes: 1 addition & 9 deletions react/assets/forus-webshop/scss/includes/components/_label.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@
}
}

.label-close {
color: #fff;
float: left;
font-size: 14px;
margin: 0 2.5px 0 -2.5px;
cursor: pointer;
}

&.label-success {
color: var(--label-success-color);
background: var(--label-success-background);
Expand Down Expand Up @@ -109,4 +101,4 @@
border-radius: calc(var(--border-radius) / 2);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { uniq, uniqueId } from 'lodash';
import SelectControl from '../../select-control/SelectControl';
import Label from '../../image_cropper/Label';
import Label from '../../label/Label';

export default function MultiSelectControl<T = number>({
id = uniqueId('multiselect_'),
Expand Down Expand Up @@ -70,9 +70,13 @@ export default function MultiSelectControl<T = number>({
<label className="form-label">&nbsp;</label>

{value?.map((id) => (
<Label type="primary" key={id.toString()}>
<Label
type="primary"
key={id.toString()}
icon="close"
iconPosition="close"
iconOnClick={() => removeItem(id)}>
{optionsById?.[id.toString()] || ''}
<div className="mdi mdi-close label-close" onClick={() => removeItem(id)} />
</Label>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ export default function ImageCropper({
'cover',
).toBlob(
(blob) => resolve({ ...item, blob, data: blob ? createObjectURL(blob) : null }),
file.type,
'image/jpeg',
quality,
);
});
},
[file.type, img, quality],
[img, quality],
);

const onComplete = useCallback(
Expand Down
62 changes: 62 additions & 0 deletions react/src/dashboard/components/elements/label/Label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import classNames from 'classnames';
import React, { ReactNode } from 'react';

export type LabelType =
| 'success'
| 'warning'
| 'danger'
| 'danger-light'
| 'default'
| 'text'
| 'primary'
| 'primary-light';

export default function Label({
children,
type,
className,
dusk,
icon,
iconPosition = 'start',
iconOnClick,
nowrap,
}: {
children?: ReactNode | ReactNode[];
type?: LabelType;
className?: string;
dusk?: string;
icon?: string;
iconPosition?: 'start' | 'end' | 'close';
iconOnClick?: React.MouseEventHandler<HTMLElement>;
nowrap?: boolean;
}) {
const iconClassName = classNames(
iconPosition === 'close' ? 'label-close' : iconPosition === 'end' ? 'icon-end' : 'icon-start',
);

const iconElement = icon ? (
<em className={classNames('mdi', `mdi-${icon}`, iconClassName)} onClick={iconOnClick} />
) : null;

return (
<div
data-dusk={dusk}
className={classNames(
'label',
type === 'success' && 'label-success',
type === 'warning' && 'label-warning',
type === 'danger' && 'label-danger',
type === 'danger-light' && 'label-danger-light',
type === 'default' && 'label-default',
type === 'text' && 'label-text',
type === 'primary' && 'label-primary',
type === 'primary-light' && 'label-primary-light',
nowrap && 'nowrap',
className,
)}>
{iconPosition === 'start' && iconElement}
{children}
{iconPosition !== 'start' && iconElement}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { uniqueId } from 'lodash';
import useOpenModal from '../../../hooks/useOpenModal';
import useAssetUrl from '../../../hooks/useAssetUrl';
import useTranslate from '../../../hooks/useTranslate';
import usePushDanger from '../../../hooks/usePushDanger';
import useFileTypeValidation from '../../../services/helpers/useFileTypeValidation';

export default function PhotoSelector({
id,
Expand Down Expand Up @@ -36,17 +38,31 @@ export default function PhotoSelector({

const assetUrl = useAssetUrl();
const openModal = useOpenModal();
const pushDanger = usePushDanger();
const fileTypeIsValid = useFileTypeValidation();

const [acceptedFiles] = useState(['.png', '.jpg', '.jpeg', '.svg', '.webp', '.gif', '.bmp']);
const acceptedFilesLabel = acceptedFiles.map((item) => item.toUpperCase()).join(', ');

const onPhotoChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files[0];
e.target.value = null;

if (!file) {
return;
}

if (!fileTypeIsValid(file, acceptedFiles)) {
return pushDanger(`Toegestaande formaten: ${acceptedFilesLabel}`);
}

openModal((modal) => (
<ModalPhotoUploader
type={type}
file={file}
modal={modal}
acceptedFiles={acceptedFiles}
onSubmit={(file, presets) => {
const thumbnail = presets.find((preset) => preset.key == 'thumbnail');

Expand All @@ -56,7 +72,7 @@ export default function PhotoSelector({
/>
));
},
[openModal, selectPhoto, type],
[acceptedFiles, acceptedFilesLabel, fileTypeIsValid, openModal, pushDanger, selectPhoto, type],
);

useEffect(() => {
Expand All @@ -70,7 +86,13 @@ export default function PhotoSelector({
<img src={thumbnailValue || assetUrl('/assets/img/placeholders/image-thumbnail.png')} alt="" />
</label>
<div className="photo-details">
<input type="file" hidden={true} accept={'image/*'} ref={inputRef} onChange={onPhotoChange} />
<input
type="file"
hidden={true}
accept={acceptedFiles.join(',')}
ref={inputRef}
onChange={onPhotoChange}
/>
<div className="photo-label">{label || translate('photo_selector.labels.image')}</div>
{description && <div className="photo-description">{description}</div>}

Expand All @@ -92,7 +114,13 @@ export default function PhotoSelector({
return (
<div className="block block-photo-selector">
<label htmlFor={id ? id : `photo_selector_${selectorId}`} className="photo-img">
<input type="file" hidden={true} accept={'image/*'} ref={inputRef} onChange={onPhotoChange} />
<input
type="file"
hidden={true}
accept={acceptedFiles.join(',')}
ref={inputRef}
onChange={onPhotoChange}
/>
<img src={thumbnailValue || assetUrl('/assets/img/placeholders/photo-selector.svg')} alt="" />
</label>
<div className="photo-details">
Expand Down Expand Up @@ -125,7 +153,13 @@ export default function PhotoSelector({
<label
htmlFor={id ? id : `photo_selector_${selectorId}`}
className="photo-selector-notifications-media">
<input type="file" hidden={true} accept={'image/*'} ref={inputRef} onChange={onPhotoChange} />
<input
type="file"
hidden={true}
accept={acceptedFiles.join(',')}
ref={inputRef}
onChange={onPhotoChange}
/>
<img
src={
thumbnailValue ||
Expand All @@ -140,7 +174,7 @@ export default function PhotoSelector({
<div className="photo-selector-notifications-hint">
De afbeelding dient vierkant te zijn met een afmeting van bijvoorbeeld 400x400px.
<br />
Toegestaande formaten: JPG, PNG
Toegestaande formaten: {acceptedFilesLabel}
</div>
<div className="button-group">
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import StateNavLink from '../../../modules/state_router/StateNavLink';
import Implementation from '../../../props/models/Implementation';
import Organization from '../../../props/models/Organization';
import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder';
import useFileTypeValidation from '../../../services/helpers/useFileTypeValidation';
import usePushDanger from '../../../hooks/usePushDanger';

export default function PhotoSelectorBanner({
disabled,
Expand Down Expand Up @@ -49,6 +51,10 @@ export default function PhotoSelectorBanner({

const assetUrl = useAssetUrl();
const openModal = useOpenModal();
const pushDanger = usePushDanger();
const fileTypeIsValid = useFileTypeValidation();

const [acceptedFiles] = useState(['.png', '.jpg', '.jpeg', '.svg', '.webp', '.gif', '.bmp']);
const [activeDropdown, setActiveDropdown] = useState<'style' | 'button' | 'color' | 'background' | 'overlay'>(null);
const [descriptionPreview, setDescriptionPreview] = useState<string>(null);

Expand Down Expand Up @@ -78,12 +84,23 @@ export default function PhotoSelectorBanner({
const file = e.target.files[0];
e.target.value = null;

if (!file) {
return;
}

if (!fileTypeIsValid(file, acceptedFiles)) {
return pushDanger(
`Toegestaande formaten: ${acceptedFiles.map((item) => item.toUpperCase()).join(', ')}`,
);
}

openModal((modal) => (
<ModalPhotoUploader
type={'implementation_banner'}
file={file}
modal={modal}
initialCropWidth={100}
acceptedFiles={acceptedFiles}
onSubmit={(file, presets) => {
const thumbnail = presets.find((preset) => preset.key == 'final');

Expand All @@ -93,7 +110,7 @@ export default function PhotoSelectorBanner({
/>
));
},
[openModal, selectPhoto],
[acceptedFiles, fileTypeIsValid, openModal, pushDanger, selectPhoto],
);

useEffect(() => {
Expand All @@ -113,7 +130,7 @@ export default function PhotoSelectorBanner({

return (
<div className="block block-banner-editor">
<input type="file" hidden={true} accept={'image/*'} ref={inputRef} onChange={onPhotoChange} />
<input type="file" hidden={true} accept={acceptedFiles.join(',')} ref={inputRef} onChange={onPhotoChange} />

<div
className={classNames(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import TableEmptyValue from '../table-empty-value/TableEmptyValue';
import FundForm from '../../../props/models/FundForm';
import Label from '../image_cropper/Label';
import Label from '../label/Label';

export default function FundFormStateLabels({ fundForm }: { fundForm: FundForm }) {
if (fundForm.state == 'active') {
return <Label type={'success'}>{fundForm.state_locale}</Label>;
return <Label type="success">{fundForm.state_locale}</Label>;
}

if (fundForm.state == 'archived') {
return <Label type={'default'}>{fundForm.state_locale}</Label>;
return <Label type="default">{fundForm.state_locale}</Label>;
}

return <TableEmptyValue />;
Expand Down
Loading