Thêm tính năng owner có thể thêm thành viên, member thêm thành viên sẽ pending

This commit is contained in:
3dtours committed 2026-06-14 22:14:40 +07:00
1 parent 7cc724a133
commit c6341aa12f
16 files changed
+395 -23

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
import React from 'react';
export interface NotificationModalProps {
isOpen: boolean;
title?: string;
message: string;
onConfirm?: () => void;
onCancel?: () => void;
type?: 'info' | 'success' | 'warning' | 'error';
confirmButtonText?: string;
cancelButtonText?: string;
}
export declare const NotificationModal: React.FC<NotificationModalProps>;
export declare const useNotificationModal: () => {
modalState: {
isOpen: boolean;
title?: string;
message: string;
type?: "info" | "success" | "warning" | "error";
onConfirm?: () => void;
onCancel?: () => void;
};
openModal: (title: string, message: string, type?: "info" | "success" | "warning" | "error", onConfirm?: () => void, onCancel?: () => void) => () => void;
closeModal: () => void;
};
export default NotificationModal;
+81
View File
@@ -0,0 +1,81 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
const Icons = {
info: (props) => (_jsxs("svg", { ...props, viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2" }), _jsx("path", { d: "M12 16v-4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }), _jsx("path", { d: "M12 8h.01", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" })] })),
success: (props) => (_jsxs("svg", { ...props, viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2" }), _jsx("path", { d: "M8 12l2.5 2.5L15.5 9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] })),
warning: (props) => (_jsxs("svg", { ...props, viewBox: "0 0 24 24", fill: "none", children: [_jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z", stroke: "currentColor", strokeWidth: "2" }), _jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }), _jsx("circle", { cx: "12", cy: "17", r: "1", fill: "currentColor" })] })),
error: (props) => (_jsxs("svg", { ...props, viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2" }), _jsx("line", { x1: "15", y1: "9", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }), _jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })] })),
};
const defaultProps = {
title: 'Thông báo',
type: 'info',
confirmButtonText: 'OK',
cancelButtonText: 'Hủy',
};
export const NotificationModal = ({ isOpen, title = defaultProps.title, message, onConfirm, onCancel, type = defaultProps.type, confirmButtonText = defaultProps.confirmButtonText, cancelButtonText = defaultProps.cancelButtonText, }) => {
const [isAnimating, setIsAnimating] = useState(false);
const getTypeStyles = () => {
switch (type) {
case 'success':
return { bg: '#d4edda', border: '#c3e6cb', text: '#155724' };
case 'warning':
return { bg: '#fff3cd', border: '#ffeeba', text: '#856404' };
case 'error':
return { bg: '#f8d7da', border: '#f5c6cb', text: '#721c24' };
default:
return { bg: '#e2e3e5', border: '#d6d8db', text: '#383d41' };
}
};
const styles = getTypeStyles();
const getAnimationClass = () => {
if (!isOpen)
return 'opacity-0 translate-y-4';
if (isAnimating && onCancel)
return 'animate-fade-out';
return 'animate-fade-in';
};
const handleConfirm = () => {
setIsAnimating(true);
onConfirm?.();
setTimeout(() => setIsAnimating(false), 300);
};
const handleCancel = () => {
setIsAnimating(true);
onCancel?.();
setTimeout(() => setIsAnimating(false), 300);
};
if (!isOpen)
return null;
return (_jsx("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-[100] p-4", children: _jsxs("div", { className: `bg-white rounded-lg shadow-xl max-w-md w-full transform transition-all duration-300 ${getAnimationClass()}`, role: "alertdialog", "aria-modal": "true", "aria-labelledby": "modal-title", "aria-describedby": "modal-message", children: [_jsx("div", { className: `p-6 border-b ${styles.border}`, children: _jsxs("div", { className: "flex items-center gap-3", children: [type === 'success' && _jsx(Icons.success, { className: "w-5 h-5 text-green-600" }), type === 'warning' && _jsx(Icons.warning, { className: "w-5 h-5 text-yellow-600" }), type === 'error' && _jsx(Icons.error, { className: "w-5 h-5 text-red-600" }), type === 'info' && _jsx(Icons.info, { className: "w-5 h-5 text-blue-600" }), _jsx("h2", { id: "modal-title", className: `text-xl font-semibold ${styles.text}`, children: title })] }) }), _jsx("div", { className: "p-6", children: _jsx("p", { id: "modal-message", className: "text-gray-700 leading-relaxed", children: message }) }), _jsxs("div", { className: `px-6 py-4 flex justify-end gap-3 border-t ${styles.border}`, children: [onCancel && (_jsx("button", { onClick: handleCancel, className: "px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-md transition-colors", children: cancelButtonText })), onConfirm && (_jsx("button", { onClick: handleConfirm, className: `px-4 py-2 text-white rounded-md font-medium transition-colors ${type === 'error'
? 'bg-red-600 hover:bg-red-700'
: 'bg-blue-600 hover:bg-blue-700'}`, children: confirmButtonText }))] })] }) }));
};
export const useNotificationModal = () => {
const [modalState, setModalState] = useState(null);
const openModal = (title, message, type = 'info', onConfirm, onCancel) => {
setModalState({
isOpen: true,
title,
message,
type,
onConfirm,
onCancel,
});
const timer = setTimeout(() => {
if (onCancel) {
setModalState((prev) => ({ ...prev, isOpen: false }));
}
}, 5000);
return () => clearTimeout(timer);
};
const closeModal = () => {
setModalState((prev) => prev ? { ...prev, isOpen: false } : null);
};
return {
modalState,
openModal,
closeModal,
};
};
export default NotificationModal;
//# sourceMappingURL=NotificationModal.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"NotificationModal.js","sourceRoot":"","sources":["../../components/NotificationModal.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAexC,MAAM,KAAK,GAAG;IACZ,IAAI,EAAE,CAAC,KAAoC,EAAE,EAAE,CAAC,CAC9C,kBAAS,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aAC7C,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,GAAG,EACvE,eAAM,CAAC,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,EAClF,eAAM,CAAC,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,IAC9E,CACP;IACD,OAAO,EAAE,CAAC,KAAoC,EAAE,EAAE,CAAC,CACjD,kBAAS,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aAC7C,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,GAAG,EACvE,eAAM,CAAC,EAAC,sBAAsB,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,GAAG,IAChH,CACP;IACD,OAAO,EAAE,CAAC,KAAoC,EAAE,EAAE,CAAC,CACjD,kBAAS,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aAC7C,eAAM,CAAC,EAAC,0FAA0F,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,GAAG,EAC3I,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,EACnG,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,EAAC,IAAI,EAAC,cAAc,GAAG,IAChD,CACP;IACD,KAAK,EAAE,CAAC,KAAoC,EAAE,EAAE,CAAC,CAC/C,kBAAS,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aAC7C,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,GAAG,EACvE,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,EAClG,eAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,IAC9F,CACP;CACF,CAAC;AAGF,MAAM,YAAY,GAAoC;IACpD,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,MAAM;IACZ,iBAAiB,EAAE,IAAI;IACvB,gBAAgB,EAAE,KAAK;CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAqC,CAAC,EAClE,MAAM,EACN,KAAK,GAAG,YAAY,CAAC,KAAK,EAC1B,OAAO,EACP,SAAS,EACT,QAAQ,EACR,IAAI,GAAG,YAAY,CAAC,IAAI,EACxB,iBAAiB,GAAG,YAAY,CAAC,iBAAiB,EAClD,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,GACjD,EAAE,EAAE;IACH,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAGtD,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,SAAS;gBACZ,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC/D,KAAK,SAAS;gBACZ,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC/D,KAAK,OAAO;gBACV,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC/D;gBACE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACjE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAG/B,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,IAAI,CAAC,MAAM;YAAE,OAAO,yBAAyB,CAAC;QAC9C,IAAI,WAAW,IAAI,QAAQ;YAAE,OAAO,kBAAkB,CAAC;QACvD,OAAO,iBAAiB,CAAC;IAC3B,CAAC,CAAC;IAGF,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,SAAS,EAAE,EAAE,CAAC;QACd,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC;IAGF,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,QAAQ,EAAE,EAAE,CAAC;QACb,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO,CACL,cAAK,SAAS,EAAC,wEAAwE,YACrF,eACE,SAAS,EAAE,uFAAuF,iBAAiB,EAAE,EAAE,EACvH,IAAI,EAAC,aAAa,gBACP,MAAM,qBACD,aAAa,sBACZ,eAAe,aAGhC,cAAK,SAAS,EAAE,gBAAgB,MAAM,CAAC,MAAM,EAAE,YAC7C,eAAK,SAAS,EAAC,yBAAyB,aACrC,IAAI,KAAK,SAAS,IAAI,KAAC,KAAK,CAAC,OAAO,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC1E,IAAI,KAAK,SAAS,IAAI,KAAC,KAAK,CAAC,OAAO,IAAC,SAAS,EAAC,yBAAyB,GAAG,EAC3E,IAAI,KAAK,OAAO,IAAI,KAAC,KAAK,CAAC,KAAK,IAAC,SAAS,EAAC,sBAAsB,GAAG,EACpE,IAAI,KAAK,MAAM,IAAI,KAAC,KAAK,CAAC,IAAI,IAAC,SAAS,EAAC,uBAAuB,GAAG,EACpE,aAAI,EAAE,EAAC,aAAa,EAAC,SAAS,EAAE,yBAAyB,MAAM,CAAC,IAAI,EAAE,YACnE,KAAK,GACH,IACD,GACF,EAGN,cAAK,SAAS,EAAC,KAAK,YAClB,YAAG,EAAE,EAAC,eAAe,EAAC,SAAS,EAAC,+BAA+B,YAAE,OAAO,GAAK,GACzE,EAGN,eAAK,SAAS,EAAE,6CAA6C,MAAM,CAAC,MAAM,EAAE,aACzE,QAAQ,IAAI,CACX,iBACE,OAAO,EAAE,YAAY,EACrB,SAAS,EAAC,wEAAwE,YAEjF,gBAAgB,GACV,CACV,EACA,SAAS,IAAI,CACZ,iBACE,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,iEACT,IAAI,KAAK,OAAO;gCACd,CAAC,CAAC,6BAA6B;gCAC/B,CAAC,CAAC,+BACN,EAAE,YAED,iBAAiB,GACX,CACV,IACG,IACF,GACF,CACP,CAAC;AACJ,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE;IACvC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAOlC,IAAI,CAAC,CAAC;IAEhB,MAAM,SAAS,GAAG,CAChB,KAAa,EACb,OAAe,EACf,OAAiD,MAAM,EACvD,SAAsB,EACtB,QAAqB,EACrB,EAAE;QACF,aAAa,CAAC;YACZ,MAAM,EAAE,IAAI;YACZ,KAAK;YACL,OAAO;YACP,IAAI;YACJ,SAAS;YACT,QAAQ;SACT,CAAC,CAAC;QAGH,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,QAAQ,EAAE,CAAC;gBACb,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,aAAa,CAAC,CAAC,IAAI,EALine truncated