76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import React, { type FormEvent, type ReactNode } from "react";
|
|
|
|
interface FormModalProps {
|
|
children: ReactNode;
|
|
description?: string;
|
|
isSaving: boolean;
|
|
onClose: () => void;
|
|
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
|
submitDisabled?: boolean;
|
|
submitLabel: string;
|
|
title: string;
|
|
}
|
|
|
|
export function FormModal({
|
|
children,
|
|
description,
|
|
isSaving,
|
|
onClose,
|
|
onSubmit,
|
|
submitDisabled,
|
|
submitLabel,
|
|
title,
|
|
}: FormModalProps) {
|
|
return (
|
|
<>
|
|
<div
|
|
aria-modal="true"
|
|
className="modal fade show d-block"
|
|
role="dialog"
|
|
tabIndex={-1}
|
|
>
|
|
<div className="modal-dialog modal-lg modal-dialog-centered">
|
|
<form className="modal-content" onSubmit={onSubmit}>
|
|
<div className="modal-header">
|
|
<div>
|
|
<h2 className="modal-title fs-5">{title}</h2>
|
|
{description ? (
|
|
<p className="text-secondary small mb-0">{description}</p>
|
|
) : null}
|
|
</div>
|
|
<button
|
|
aria-label="Schließen"
|
|
className="btn-close"
|
|
disabled={isSaving}
|
|
onClick={onClose}
|
|
type="button"
|
|
/>
|
|
</div>
|
|
<div className="modal-body">{children}</div>
|
|
<div className="modal-footer">
|
|
<button
|
|
className="btn btn-outline-secondary"
|
|
disabled={isSaving}
|
|
onClick={onClose}
|
|
type="button"
|
|
>
|
|
Abbrechen
|
|
</button>
|
|
<button
|
|
className="btn btn-primary"
|
|
disabled={isSaving || submitDisabled}
|
|
type="submit"
|
|
>
|
|
{isSaving ? "Wird gespeichert …" : submitLabel}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div className="modal-backdrop fade show" />
|
|
</>
|
|
);
|
|
}
|