feat: add custom field type of image

This commit is contained in:
Carlos Valente
2025-02-19 20:29:13 +01:00
committed by Carlos Valente
parent d0b4c6a279
commit 570ff59cfc
18 changed files with 306 additions and 56 deletions
@@ -78,3 +78,9 @@
font-size: 1.25em;
margin-left: 0.25em;
}
.customImage {
display: grid;
grid-template-columns: 1fr 72px;
gap: 1rem;
}
@@ -8,9 +8,11 @@ import useCustomFields from '../../../common/hooks-query/useCustomFields';
import { getAccessibleColour } from '../../../common/utils/styleUtils';
import * as Editor from '../../editors/editor-utils/EditorUtils';
import EventEditorImage from './composite/EventEditorImage';
import EventEditorTimes from './composite/EventEditorTimes';
import EventEditorTitles from './composite/EventEditorTitles';
import EventTextArea from './composite/EventTextArea';
import EventTextInput from './composite/EventTextInput';
import EventEditorEmpty from './EventEditorEmpty';
import style from './EventEditor.module.scss';
@@ -87,6 +89,7 @@ export default function EventEditor(props: EventEditorProps) {
</Button>
)}
</Editor.Title>
{Object.keys(customFields).map((fieldKey) => {
const key = `${event.id}-${fieldKey}`;
const fieldName = `custom-${fieldKey}`;
@@ -94,17 +97,41 @@ export default function EventEditor(props: EventEditorProps) {
const { backgroundColor, color } = getAccessibleColour(customFields[fieldKey].colour);
const labelText = customFields[fieldKey].label;
return (
<EventTextArea
key={key}
field={fieldName}
label={labelText}
initialValue={initialValue}
submitHandler={handleSubmit}
className={style.decorated}
style={{ '--decorator-bg': backgroundColor, '--decorator-color': color } as CSSProperties}
/>
);
if (customFields[fieldKey].type === 'string') {
return (
<EventTextArea
key={key}
field={fieldName}
label={labelText}
initialValue={initialValue}
submitHandler={handleSubmit}
className={style.decorated}
style={{ '--decorator-bg': backgroundColor, '--decorator-color': color } as CSSProperties}
/>
);
}
if (customFields[fieldKey].type === 'image') {
return (
<div key={key} className={style.customImage}>
<EventTextInput
key={key}
field={fieldName}
label={labelText}
initialValue={initialValue}
placeholder='Paste image URL'
submitHandler={handleSubmit}
className={style.decorated}
maxLength={255}
style={{ '--decorator-bg': backgroundColor, '--decorator-color': color } as CSSProperties}
/>
<EventEditorImage src={initialValue} />
</div>
);
}
// we should have exhausted all types by now
return null;
})}
</div>
</div>
@@ -0,0 +1,12 @@
.imageContainer {
width: 100%;
height: 100%;
background-color: $gray-1250;
display: grid;
place-content: center;
}
.imageOverlay {
width: 100%;
height: 100%;
}
@@ -0,0 +1,16 @@
import style from './EventEditorImage.module.scss';
interface EventEditorImageProps {
src: string;
}
export default function EventEditorImage(props: EventEditorImageProps) {
const { src } = props;
return (
<div className={style.imageContainer}>
<img loading='lazy' src={src} />
<div className={style.imageOverlay} />
</div>
);
}
@@ -9,11 +9,12 @@ interface EventTextInputProps extends InputProps {
field: EditorUpdateFields;
label: string;
initialValue: string;
placeholder?: string;
submitHandler: (field: EditorUpdateFields, value: string) => void;
}
export default function EventTextInput(props: EventTextInputProps) {
const { field, label, initialValue, submitHandler, maxLength } = props;
const { className, field, label, initialValue, style: givenStyles, submitHandler, maxLength, placeholder } = props;
const ref = useRef<HTMLInputElement | null>(null);
const submitCallback = useCallback((newValue: string) => submitHandler(field, newValue), [field, submitHandler]);
@@ -23,7 +24,9 @@ export default function EventTextInput(props: EventTextInputProps) {
return (
<div>
<Editor.Label htmlFor={field}>{label}</Editor.Label>
<Editor.Label className={className} htmlFor={field} style={givenStyles}>
{label}
</Editor.Label>
<Input
id={field}
ref={ref}
@@ -32,6 +35,7 @@ export default function EventTextInput(props: EventTextInputProps) {
data-testid='input-textfield'
value={value}
maxLength={maxLength || 100}
placeholder={placeholder}
onChange={onChange}
onBlur={onBlur}
onKeyDown={onKeyDown}