feat: Update Wedding Guest Forms with Create-Project Styling
- Copy CSS and styling patterns from create-project to add-wedding-guest page - Update edit-wedding-guest to match add-wedding-guest structure and design - Add form-group-header with icons (FileText, Users, Gift) for visual hierarchy - Implement Bootstrap grid layout (col-lg-*, row, mb-3) for consistent spacing - Add LoadingButton component with advanced loading states - Fix dropdown lists background-color for dark theme compatibility - Remove className='form-control' from Ant Design Select components to prevent conflicts - Add comprehensive dark theme CSS support for dropdowns and form elements - Update form structure to use card/card-body instead of Ant Design Card - Implement consistent button styling with create-project-btn and btn-cancel-project classes - Add transparent background for wedding guest search input elements - Update status options: Confirmed, Pending, Cancelled, Attended with emojis
This commit is contained in:
parent
af93a1fd6a
commit
68355e31a8
@ -1,8 +1,9 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Form, Input, InputNumber, Select, Button, Card, message, Row, Col } from 'antd';
|
import { Form, Input, InputNumber, Select, message } from 'antd';
|
||||||
import { useNavigate, Link } from 'react-router-dom';
|
import { useNavigate, Link } from 'react-router-dom';
|
||||||
import { ArrowLeft, Save, Heart } from 'react-feather';
|
import { ArrowLeft, Save, Users, FileText, Gift } from 'react-feather';
|
||||||
import { weddingGuestService } from '../../services/weddingGuestService';
|
import { weddingGuestService } from '../../services/weddingGuestService';
|
||||||
|
import { LoadingButton } from '../../components/Loading';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
@ -54,135 +55,153 @@ const AddWeddingGuest = () => {
|
|||||||
<div className="page-wrapper">
|
<div className="page-wrapper">
|
||||||
<style>
|
<style>
|
||||||
{`
|
{`
|
||||||
/* Force light theme styles for all form elements */
|
/* Dropdown Lists Dark Theme Styling for Add Wedding Guest */
|
||||||
.page-wrapper .content .ant-form-item-label > label,
|
|
||||||
.page-wrapper .content .ant-form-item label {
|
/* Light Mode Dropdown Styling */
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-selector,
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-single .ant-select-selector,
|
||||||
|
body.light-mode .ant-select-selector,
|
||||||
|
body.light .ant-select-selector {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-color: #d9d9d9 !important;
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-wrapper .content .ant-input,
|
html[data-layout-mode="light_mode"] .ant-select-dropdown,
|
||||||
.page-wrapper .content .ant-input-number,
|
body.light-mode .ant-select-dropdown,
|
||||||
.page-wrapper .content .ant-input-number-input,
|
body.light .ant-select-dropdown {
|
||||||
.page-wrapper .content .ant-select-selection-item,
|
|
||||||
.page-wrapper .content .ant-select-selector,
|
|
||||||
.page-wrapper .content .ant-select-single .ant-select-selector,
|
|
||||||
.page-wrapper .content textarea.ant-input {
|
|
||||||
color: #000000 !important;
|
|
||||||
background-color: #ffffff !important;
|
background-color: #ffffff !important;
|
||||||
border-color: #d9d9d9 !important;
|
border-color: #d9d9d9 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-wrapper .content .ant-input:focus,
|
html[data-layout-mode="light_mode"] .ant-select-item,
|
||||||
.page-wrapper .content .ant-input-number:focus,
|
body.light-mode .ant-select-item,
|
||||||
.page-wrapper .content .ant-input-number-input:focus,
|
body.light .ant-select-item {
|
||||||
.page-wrapper .content .ant-select-focused .ant-select-selector,
|
|
||||||
.page-wrapper .content textarea.ant-input:focus {
|
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
background-color: #ffffff !important;
|
background-color: #ffffff !important;
|
||||||
border-color: #40a9ff !important;
|
|
||||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-wrapper .content .ant-input::placeholder,
|
html[data-layout-mode="light_mode"] .ant-select-item:hover,
|
||||||
.page-wrapper .content .ant-input-number-input::placeholder,
|
body.light-mode .ant-select-item:hover,
|
||||||
.page-wrapper .content textarea.ant-input::placeholder {
|
body.light .ant-select-item:hover {
|
||||||
color: #999999 !important;
|
background-color: #f5f5f5 !important;
|
||||||
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-wrapper .content .ant-card {
|
html[data-layout-mode="light_mode"] .ant-select-item-option-selected,
|
||||||
background-color: #ffffff !important;
|
body.light-mode .ant-select-item-option-selected,
|
||||||
border-color: #d9d9d9 !important;
|
body.light .ant-select-item-option-selected {
|
||||||
}
|
background-color: #1890ff !important;
|
||||||
|
|
||||||
/* Dark theme overrides */
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-form-item-label > label,
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-form-item label {
|
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input,
|
/* Dark Mode Dropdown Styling */
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input-number,
|
html[data-layout-mode="dark_mode"] .ant-select-selector,
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input-number-input,
|
html[data-layout-mode="dark_mode"] .ant-select-single .ant-select-selector,
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-selection-item,
|
body.dark-mode .ant-select-selector,
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-selector,
|
body.dark .ant-select-selector {
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-single .ant-select-selector,
|
background-color: #141432 !important;
|
||||||
[data-theme="dark"] .page-wrapper .content textarea.ant-input {
|
|
||||||
color: #ffffff !important;
|
|
||||||
background-color: #1f1f1f !important;
|
|
||||||
border-color: #434343 !important;
|
border-color: #434343 !important;
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input:focus,
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input-number:focus,
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input-number-input:focus,
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-focused .ant-select-selector,
|
|
||||||
[data-theme="dark"] .page-wrapper .content textarea.ant-input:focus {
|
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
background-color: #1f1f1f !important;
|
|
||||||
border-color: #177ddc !important;
|
|
||||||
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input::placeholder,
|
html[data-layout-mode="dark_mode"] .ant-select-dropdown,
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-input-number-input::placeholder,
|
body.dark-mode .ant-select-dropdown,
|
||||||
[data-theme="dark"] .page-wrapper .content textarea.ant-input::placeholder {
|
body.dark .ant-select-dropdown {
|
||||||
color: #888888 !important;
|
background-color: #141432 !important;
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-card {
|
|
||||||
background-color: #1f1f1f !important;
|
|
||||||
border-color: #434343 !important;
|
border-color: #434343 !important;
|
||||||
|
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 9px 28px 8px rgba(0, 0, 0, 0.2) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-dropdown {
|
html[data-layout-mode="dark_mode"] .ant-select-item,
|
||||||
background-color: #1f1f1f !important;
|
body.dark-mode .ant-select-item,
|
||||||
border-color: #434343 !important;
|
body.dark .ant-select-item {
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-item {
|
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
background-color: #1f1f1f !important;
|
background-color: #141432 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-item:hover {
|
html[data-layout-mode="dark_mode"] .ant-select-item:hover,
|
||||||
|
body.dark-mode .ant-select-item:hover,
|
||||||
|
body.dark .ant-select-item:hover {
|
||||||
background-color: #434343 !important;
|
background-color: #434343 !important;
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .page-wrapper .content .ant-select-item-option-selected {
|
html[data-layout-mode="dark_mode"] .ant-select-item-option-selected,
|
||||||
|
body.dark-mode .ant-select-item-option-selected,
|
||||||
|
body.dark .ant-select-item-option-selected {
|
||||||
background-color: #177ddc !important;
|
background-color: #177ddc !important;
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* System dark theme detection */
|
/* Dropdown Arrow Icon Dark Mode */
|
||||||
@media (prefers-color-scheme: dark) {
|
html[data-layout-mode="dark_mode"] .ant-select-arrow,
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-form-item-label > label,
|
body.dark-mode .ant-select-arrow,
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-form-item label {
|
body.dark .ant-select-arrow {
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-input,
|
/* Focus States for Dark Mode */
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-input-number,
|
html[data-layout-mode="dark_mode"] .ant-select-focused .ant-select-selector,
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-input-number-input,
|
body.dark-mode .ant-select-focused .ant-select-selector,
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-select-selection-item,
|
body.dark .ant-select-focused .ant-select-selector {
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-select-selector,
|
background-color: #141432 !important;
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-select-single .ant-select-selector,
|
border-color: #177ddc !important;
|
||||||
body:not([data-theme="light"]) .page-wrapper .content textarea.ant-input {
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
color: #ffffff !important;
|
}
|
||||||
background-color: #1f1f1f !important;
|
|
||||||
border-color: #434343 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-input::placeholder,
|
/* Placeholder Text Dark Mode */
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-input-number-input::placeholder,
|
html[data-layout-mode="dark_mode"] .ant-select-selection-placeholder,
|
||||||
body:not([data-theme="light"]) .page-wrapper .content textarea.ant-input::placeholder {
|
body.dark-mode .ant-select-selection-placeholder,
|
||||||
color: #888888 !important;
|
body.dark .ant-select-selection-placeholder {
|
||||||
}
|
color: #888888 !important;
|
||||||
|
}
|
||||||
|
|
||||||
body:not([data-theme="light"]) .page-wrapper .content .ant-card {
|
/* Input Number Dark Mode Styling */
|
||||||
background-color: #1f1f1f !important;
|
html[data-layout-mode="dark_mode"] .ant-input-number,
|
||||||
border-color: #434343 !important;
|
html[data-layout-mode="dark_mode"] .ant-input-number-input,
|
||||||
}
|
body.dark-mode .ant-input-number,
|
||||||
|
body.dark .ant-input-number {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number:focus,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number-focused,
|
||||||
|
body.dark-mode .ant-input-number:focus,
|
||||||
|
body.dark .ant-input-number:focus {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TextArea Dark Mode Styling */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input,
|
||||||
|
body.dark-mode .ant-input,
|
||||||
|
body.dark textarea.ant-input {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input:focus,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input:focus,
|
||||||
|
body.dark-mode .ant-input:focus,
|
||||||
|
body.dark textarea.ant-input:focus {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder Text for Inputs */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input::placeholder,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number-input::placeholder,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input::placeholder,
|
||||||
|
body.dark-mode .ant-input::placeholder,
|
||||||
|
body.dark .ant-input::placeholder {
|
||||||
|
color: #888888 !important;
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
@ -191,171 +210,230 @@ const AddWeddingGuest = () => {
|
|||||||
<div className="page-header">
|
<div className="page-header">
|
||||||
<div className="add-item d-flex">
|
<div className="add-item d-flex">
|
||||||
<div className="page-title">
|
<div className="page-title">
|
||||||
<h4>
|
<h4>Thêm khách mời đám cưới</h4>
|
||||||
<Heart size={20} style={{ marginRight: '8px', color: '#ff69b4' }} />
|
<h6>Tạo thông tin khách mời mới cho đám cưới</h6>
|
||||||
Thêm khách mời đám cưới
|
|
||||||
</h4>
|
|
||||||
<h6>Thêm khách mời mới vào danh sách</h6>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="page-btn">
|
<div className="page-btn">
|
||||||
<Link to="/wedding-guest-list">
|
<Link to="/wedding-guest-list" className="btn btn-added">
|
||||||
<Button
|
<ArrowLeft className="me-2" size={16} />
|
||||||
type="default"
|
Quay lại danh sách
|
||||||
icon={<ArrowLeft size={16} />}
|
|
||||||
>
|
|
||||||
Quay lại
|
|
||||||
</Button>
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Form */}
|
{/* Form */}
|
||||||
<Card>
|
<div className="card">
|
||||||
<Form
|
<div className="card-body">
|
||||||
form={form}
|
<Form
|
||||||
layout="vertical"
|
form={form}
|
||||||
onFinish={handleSubmit}
|
layout="vertical"
|
||||||
autoComplete="off"
|
onFinish={handleSubmit}
|
||||||
initialValues={{
|
autoComplete="off"
|
||||||
numberOfPeople: 1,
|
initialValues={{
|
||||||
giftAmount: 0,
|
numberOfPeople: 1,
|
||||||
status: 'Pending'
|
giftAmount: 0,
|
||||||
}}
|
status: 'Pending'
|
||||||
>
|
}}
|
||||||
<Row gutter={24}>
|
>
|
||||||
<Col xs={24} sm={12}>
|
<div className="row">
|
||||||
<Form.Item
|
{/* Guest Basic Info */}
|
||||||
label="Tên khách mời"
|
<div className="col-lg-12">
|
||||||
name="name"
|
<div className="form-group-header">
|
||||||
rules={[
|
<div className="form-group-icon">
|
||||||
{ required: true, message: 'Vui lòng nhập tên khách mời!' },
|
<FileText size={20} />
|
||||||
{ min: 2, message: 'Tên phải có ít nhất 2 ký tự!' }
|
</div>
|
||||||
]}
|
<h5>Thông tin khách mời</h5>
|
||||||
>
|
</div>
|
||||||
<Input placeholder="Nhập tên khách mời" />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={12}>
|
|
||||||
<Form.Item
|
|
||||||
label="Đơn vị"
|
|
||||||
name="unit"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng nhập đơn vị!' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="Nhập đơn vị" />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label="Số người"
|
|
||||||
name="numberOfPeople"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Vui lòng nhập số người!' },
|
|
||||||
{ type: 'number', min: 1, message: 'Số người phải lớn hơn 0!' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
placeholder="Nhập số người"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
min={1}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label="Số tiền mừng (VND)"
|
|
||||||
name="giftAmount"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Vui lòng nhập số tiền mừng!' },
|
|
||||||
{ type: 'number', min: 0, message: 'Số tiền phải lớn hơn hoặc bằng 0!' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
placeholder="Nhập số tiền mừng"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
min={0}
|
|
||||||
formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
|
||||||
parser={value => value.replace(/\$\s?|(,*)/g, '')}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label="Trạng thái"
|
|
||||||
name="status"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng chọn trạng thái!' }]}
|
|
||||||
>
|
|
||||||
<Select placeholder="Chọn trạng thái">
|
|
||||||
<Option value="Going">✅ Đi</Option>
|
|
||||||
<Option value="NotGoing">❌ Không đi</Option>
|
|
||||||
<Option value="Pending">⏳ Chưa xác nhận</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24} sm={12}>
|
|
||||||
<Form.Item
|
|
||||||
label="Mối quan hệ"
|
|
||||||
name="relationship"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng chọn mối quan hệ!' }]}
|
|
||||||
>
|
|
||||||
<Select placeholder="Chọn mối quan hệ">
|
|
||||||
<Option value="Family">👨👩👧👦 Gia đình</Option>
|
|
||||||
<Option value="Friend">👫 Bạn bè</Option>
|
|
||||||
<Option value="Colleague">💼 Đồng nghiệp</Option>
|
|
||||||
<Option value="Relative">👥 Họ hàng</Option>
|
|
||||||
<Option value="Other">🤝 Khác</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24}>
|
|
||||||
<Form.Item
|
|
||||||
label="Ghi chú"
|
|
||||||
name="notes"
|
|
||||||
>
|
|
||||||
<TextArea
|
|
||||||
placeholder="Nhập ghi chú (tùy chọn)"
|
|
||||||
rows={4}
|
|
||||||
maxLength={500}
|
|
||||||
showCount
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row>
|
|
||||||
<Col xs={24}>
|
|
||||||
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end' }}>
|
|
||||||
<Link to="/wedding-guest-list">
|
|
||||||
<Button type="default">
|
|
||||||
Hủy
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
htmlType="submit"
|
|
||||||
loading={submitting}
|
|
||||||
icon={<Save size={16} />}
|
|
||||||
style={{ backgroundColor: '#ff69b4', borderColor: '#ff69b4' }}
|
|
||||||
>
|
|
||||||
Thêm khách mời
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
|
||||||
</Row>
|
<div className="col-lg-6">
|
||||||
</Form>
|
<div className="mb-3">
|
||||||
</Card>
|
<label className="form-label">Tên khách mời <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="name"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập tên khách mời!' },
|
||||||
|
{ min: 2, message: 'Tên phải có ít nhất 2 ký tự!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Nhập tên khách mời"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-6">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Đơn vị <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="unit"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng nhập đơn vị!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Nhập đơn vị"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
{/* Guest Details */}
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group-header">
|
||||||
|
<div className="form-group-icon">
|
||||||
|
<Users size={20} />
|
||||||
|
</div>
|
||||||
|
<h5>Chi tiết khách mời</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Số người <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="numberOfPeople"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập số người!' },
|
||||||
|
{ type: 'number', min: 1, message: 'Số người phải lớn hơn 0!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
placeholder="Nhập số người"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
min={1}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Số tiền mừng (VND) <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="giftAmount"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập số tiền mừng!' },
|
||||||
|
{ type: 'number', min: 0, message: 'Số tiền phải lớn hơn hoặc bằng 0!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
placeholder="Nhập số tiền mừng"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
min={0}
|
||||||
|
formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
||||||
|
parser={value => value.replace(/\$\s?|(,*)/g, '')}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Trạng thái <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="status"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng chọn trạng thái!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="Chọn trạng thái"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<Option value="Confirmed">✅ Đã xác nhận</Option>
|
||||||
|
<Option value="Pending">⏳ Chưa xác nhận</Option>
|
||||||
|
<Option value="Cancelled">❌ Hủy</Option>
|
||||||
|
<Option value="Attended">👥 Đã tham dự</Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
{/* Additional Info */}
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group-header">
|
||||||
|
<div className="form-group-icon">
|
||||||
|
<Gift size={20} />
|
||||||
|
</div>
|
||||||
|
<h5>Thông tin bổ sung</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-6">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Mối quan hệ <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="relationship"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng chọn mối quan hệ!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="Chọn mối quan hệ"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<Option value="Family">👨👩👧👦 Gia đình</Option>
|
||||||
|
<Option value="Friend">👫 Bạn bè</Option>
|
||||||
|
<Option value="Colleague">💼 Đồng nghiệp</Option>
|
||||||
|
<Option value="Relative">👥 Họ hàng</Option>
|
||||||
|
<Option value="Other">🤝 Khác</Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Ghi chú</label>
|
||||||
|
<Form.Item
|
||||||
|
name="notes"
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
placeholder="Nhập ghi chú (tùy chọn)"
|
||||||
|
rows={4}
|
||||||
|
maxLength={500}
|
||||||
|
showCount
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Submit Buttons */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="btn-addproduct mb-4 d-flex align-items-center gap-3">
|
||||||
|
<LoadingButton
|
||||||
|
type="submit"
|
||||||
|
variant="primary"
|
||||||
|
size="medium"
|
||||||
|
loading={submitting}
|
||||||
|
loadingText="Đang thêm khách mời..."
|
||||||
|
className="create-project-btn"
|
||||||
|
icon={<Save size={16} />}
|
||||||
|
>
|
||||||
|
Thêm khách mời
|
||||||
|
</LoadingButton>
|
||||||
|
|
||||||
|
<Link to="/wedding-guest-list" className="btn btn-cancel btn-cancel-project">
|
||||||
|
Hủy
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Form, Input, InputNumber, Select, Button, Card, message, Spin, Row, Col } from 'antd';
|
import { Form, Input, InputNumber, Select, message, Spin } from 'antd';
|
||||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||||
import { ArrowLeft, Save, Heart } from 'react-feather';
|
import { ArrowLeft, Save, Users, FileText, Gift } from 'react-feather';
|
||||||
import { weddingGuestService } from '../../services/weddingGuestService';
|
import { weddingGuestService } from '../../services/weddingGuestService';
|
||||||
|
import { LoadingButton } from '../../components/Loading';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
@ -14,85 +15,8 @@ const EditWeddingGuest = () => {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [guestData, setGuestData] = useState(null);
|
const [guestData, setGuestData] = useState(null);
|
||||||
const [isDarkTheme, setIsDarkTheme] = useState(false);
|
|
||||||
|
|
||||||
// Check theme with multiple approaches
|
|
||||||
useEffect(() => {
|
|
||||||
const checkTheme = () => {
|
|
||||||
const htmlElement = document.documentElement;
|
|
||||||
const bodyElement = document.body;
|
|
||||||
|
|
||||||
// Get all possible theme indicators
|
|
||||||
const layoutMode = htmlElement.getAttribute('data-layout-mode');
|
|
||||||
const dataTheme = htmlElement.getAttribute('data-theme');
|
|
||||||
const bodyClass = bodyElement.className;
|
|
||||||
const colorSchema = localStorage.getItem('colorschema');
|
|
||||||
|
|
||||||
// Check multiple ways to detect dark mode
|
|
||||||
const isDarkByLayoutMode = layoutMode === 'dark_mode';
|
|
||||||
const isDarkByDataTheme = dataTheme === 'dark';
|
|
||||||
const isDarkByLocalStorage = colorSchema === 'dark_mode';
|
|
||||||
const isDarkByBodyClass = bodyClass.includes('dark') || bodyClass.includes('dark-mode');
|
|
||||||
|
|
||||||
// Use any method that indicates dark mode
|
|
||||||
const isDark = isDarkByLayoutMode || isDarkByDataTheme || isDarkByLocalStorage || isDarkByBodyClass;
|
|
||||||
|
|
||||||
console.log('🎨 Theme debug (Edit):', {
|
|
||||||
layoutMode,
|
|
||||||
dataTheme,
|
|
||||||
bodyClass,
|
|
||||||
colorSchema,
|
|
||||||
isDarkByLayoutMode,
|
|
||||||
isDarkByDataTheme,
|
|
||||||
isDarkByLocalStorage,
|
|
||||||
isDarkByBodyClass,
|
|
||||||
finalIsDark: isDark
|
|
||||||
});
|
|
||||||
|
|
||||||
setIsDarkTheme(isDark);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initial check
|
|
||||||
checkTheme();
|
|
||||||
|
|
||||||
// Check again after a short delay to catch late theme application
|
|
||||||
setTimeout(checkTheme, 100);
|
|
||||||
setTimeout(checkTheme, 500);
|
|
||||||
|
|
||||||
// Listen for all possible theme changes
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
console.log('🔄 DOM mutation detected (Edit), rechecking theme...');
|
|
||||||
checkTheme();
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.documentElement, {
|
|
||||||
attributes: true,
|
|
||||||
attributeFilter: ['data-layout-mode', 'data-theme', 'class']
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.body, {
|
|
||||||
attributes: true,
|
|
||||||
attributeFilter: ['class', 'data-theme']
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for localStorage changes
|
|
||||||
const handleStorageChange = (e) => {
|
|
||||||
if (e.key === 'colorschema') {
|
|
||||||
console.log('📦 localStorage colorschema changed (Edit):', e.newValue);
|
|
||||||
setTimeout(checkTheme, 50);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.addEventListener('storage', handleStorageChange);
|
|
||||||
|
|
||||||
// Also check periodically as fallback
|
|
||||||
const interval = setInterval(checkTheme, 2000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
observer.disconnect();
|
|
||||||
window.removeEventListener('storage', handleStorageChange);
|
|
||||||
clearInterval(interval);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Load guest data
|
// Load guest data
|
||||||
const loadGuestData = async () => {
|
const loadGuestData = async () => {
|
||||||
@ -168,40 +92,7 @@ const EditWeddingGuest = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dynamic styles based on theme
|
|
||||||
const getInputStyle = () => ({
|
|
||||||
color: isDarkTheme ? '#ffffff' : '#000000',
|
|
||||||
backgroundColor: isDarkTheme ? '#1f1f1f' : '#ffffff',
|
|
||||||
borderColor: isDarkTheme ? '#434343' : '#d9d9d9',
|
|
||||||
});
|
|
||||||
|
|
||||||
const getLabelStyle = () => ({
|
|
||||||
color: isDarkTheme ? '#ffffff' : '#000000',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Force DOM styling update
|
|
||||||
useEffect(() => {
|
|
||||||
const forceCardStyling = () => {
|
|
||||||
// Find all ant-card elements
|
|
||||||
const cards = document.querySelectorAll('.ant-card, .wedding-guest-form');
|
|
||||||
cards.forEach(card => {
|
|
||||||
if (card) {
|
|
||||||
card.style.backgroundColor = isDarkTheme ? '#141432' : '#FAFBFE';
|
|
||||||
card.style.background = isDarkTheme ? '#141432' : '#FAFBFE';
|
|
||||||
card.style.borderColor = isDarkTheme ? '#434343' : '#d9d9d9';
|
|
||||||
card.style.color = isDarkTheme ? '#ffffff' : '#000000';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply immediately
|
|
||||||
forceCardStyling();
|
|
||||||
|
|
||||||
// Apply after a short delay to catch any late-rendered elements
|
|
||||||
const timer = setTimeout(forceCardStyling, 100);
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, [isDarkTheme]);
|
|
||||||
|
|
||||||
// Load data on component mount
|
// Load data on component mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -225,105 +116,154 @@ const EditWeddingGuest = () => {
|
|||||||
<div className="page-wrapper">
|
<div className="page-wrapper">
|
||||||
<style>
|
<style>
|
||||||
{`
|
{`
|
||||||
/* Nuclear option - override everything with maximum specificity */
|
/* Dropdown Lists Dark Theme Styling for Edit Wedding Guest */
|
||||||
div[class*="ant-card"] {
|
|
||||||
background-color: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
/* Light Mode Dropdown Styling */
|
||||||
background: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
html[data-layout-mode="light_mode"] .ant-select-selector,
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
html[data-layout-mode="light_mode"] .ant-select-single .ant-select-selector,
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
body.light-mode .ant-select-selector,
|
||||||
|
body.light .ant-select-selector {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-color: #d9d9d9 !important;
|
||||||
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Target specific CSS classes that Ant Design generates */
|
html[data-layout-mode="light_mode"] .ant-select-dropdown,
|
||||||
.css-dev-only-do-not-override-1ae8k9u,
|
body.light-mode .ant-select-dropdown,
|
||||||
[class*="css-dev-only-do-not-override"] {
|
body.light .ant-select-dropdown {
|
||||||
background-color: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
background-color: #ffffff !important;
|
||||||
background: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
border-color: #d9d9d9 !important;
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ultra high specificity for all possible selectors */
|
html[data-layout-mode="light_mode"] .ant-select-item,
|
||||||
html body div.page-wrapper div.content div.ant-card,
|
body.light-mode .ant-select-item,
|
||||||
html body div.page-wrapper div.content .ant-card,
|
body.light .ant-select-item {
|
||||||
html body .page-wrapper .content .ant-card,
|
color: #000000 !important;
|
||||||
html body .ant-card,
|
background-color: #ffffff !important;
|
||||||
.ant-card,
|
|
||||||
.wedding-guest-form {
|
|
||||||
background-color: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
background: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Form elements */
|
html[data-layout-mode="light_mode"] .ant-select-item:hover,
|
||||||
.wedding-guest-form .ant-form-item-label > label {
|
body.light-mode .ant-select-item:hover,
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
body.light .ant-select-item:hover {
|
||||||
|
background-color: #f5f5f5 !important;
|
||||||
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wedding-guest-form .ant-input,
|
html[data-layout-mode="light_mode"] .ant-select-item-option-selected,
|
||||||
.wedding-guest-form .ant-input-number-input,
|
body.light-mode .ant-select-item-option-selected,
|
||||||
.wedding-guest-form .ant-select-selector,
|
body.light .ant-select-item-option-selected {
|
||||||
.wedding-guest-form textarea {
|
background-color: #1890ff !important;
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
color: #ffffff !important;
|
||||||
background-color: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
|
||||||
background: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.wedding-guest-form .ant-input::placeholder,
|
/* Dark Mode Dropdown Styling */
|
||||||
.wedding-guest-form .ant-input-number-input::placeholder,
|
html[data-layout-mode="dark_mode"] .ant-select-selector,
|
||||||
.wedding-guest-form textarea::placeholder {
|
html[data-layout-mode="dark_mode"] .ant-select-single .ant-select-selector,
|
||||||
color: ${isDarkTheme ? '#888888' : '#999999'} !important;
|
body.dark-mode .ant-select-selector,
|
||||||
}
|
body.dark .ant-select-selector {
|
||||||
|
|
||||||
.wedding-guest-form .ant-select-selection-item {
|
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Page wrapper ant-card styling - match website background */
|
|
||||||
.page-wrapper .content .ant-card {
|
|
||||||
background-color: ${isDarkTheme ? '#141432' : '#FAFBFE'} !important;
|
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All ant-card elements in page-wrapper - match website background */
|
|
||||||
.page-wrapper .ant-card,
|
|
||||||
.page-wrapper .content .ant-card,
|
|
||||||
.page-wrapper .content .ant-card.ant-card-bordered {
|
|
||||||
background-color: ${isDarkTheme ? '#141432' : '#FAFBFE'} !important;
|
|
||||||
background: ${isDarkTheme ? '#141432' : '#FAFBFE'} !important;
|
|
||||||
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
|
||||||
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override any CSS-in-JS styles */
|
|
||||||
.page-wrapper .ant-card[style],
|
|
||||||
.page-wrapper .content .ant-card[style] {
|
|
||||||
background-color: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
background: ${isDarkTheme ? '#1f1f1f' : '#ffffff'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force dark mode styles when data-layout-mode is dark_mode - match website background */
|
|
||||||
html[data-layout-mode="dark_mode"] .page-wrapper .content .ant-card,
|
|
||||||
html[data-layout-mode="dark_mode"] .page-wrapper .ant-card,
|
|
||||||
html[data-layout-mode="dark_mode"] .wedding-guest-form,
|
|
||||||
body.dark-mode .page-wrapper .content .ant-card,
|
|
||||||
body.dark .page-wrapper .content .ant-card {
|
|
||||||
background-color: #141432 !important;
|
background-color: #141432 !important;
|
||||||
background: #141432 !important;
|
|
||||||
border-color: #434343 !important;
|
border-color: #434343 !important;
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force light mode styles when data-layout-mode is light_mode - match website background */
|
html[data-layout-mode="dark_mode"] .ant-select-dropdown,
|
||||||
html[data-layout-mode="light_mode"] .page-wrapper .content .ant-card,
|
body.dark-mode .ant-select-dropdown,
|
||||||
html[data-layout-mode="light_mode"] .page-wrapper .ant-card,
|
body.dark .ant-select-dropdown {
|
||||||
html[data-layout-mode="light_mode"] .wedding-guest-form,
|
background-color: #141432 !important;
|
||||||
body.light-mode .page-wrapper .content .ant-card,
|
border-color: #434343 !important;
|
||||||
body.light .page-wrapper .content .ant-card {
|
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 9px 28px 8px rgba(0, 0, 0, 0.2) !important;
|
||||||
background-color: #FAFBFE !important;
|
}
|
||||||
background: #FAFBFE !important;
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item,
|
||||||
|
body.dark-mode .ant-select-item,
|
||||||
|
body.dark .ant-select-item {
|
||||||
|
color: #ffffff !important;
|
||||||
|
background-color: #141432 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item:hover,
|
||||||
|
body.dark-mode .ant-select-item:hover,
|
||||||
|
body.dark .ant-select-item:hover {
|
||||||
|
background-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item-option-selected,
|
||||||
|
body.dark-mode .ant-select-item-option-selected,
|
||||||
|
body.dark .ant-select-item-option-selected {
|
||||||
|
background-color: #177ddc !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown Arrow Icon Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-arrow,
|
||||||
|
body.dark-mode .ant-select-arrow,
|
||||||
|
body.dark .ant-select-arrow {
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus States for Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-focused .ant-select-selector,
|
||||||
|
body.dark-mode .ant-select-focused .ant-select-selector,
|
||||||
|
body.dark .ant-select-focused .ant-select-selector {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder Text Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-selection-placeholder,
|
||||||
|
body.dark-mode .ant-select-selection-placeholder,
|
||||||
|
body.dark .ant-select-selection-placeholder {
|
||||||
|
color: #888888 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input Number Dark Mode Styling */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number-input,
|
||||||
|
body.dark-mode .ant-input-number,
|
||||||
|
body.dark .ant-input-number {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number:focus,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number-focused,
|
||||||
|
body.dark-mode .ant-input-number:focus,
|
||||||
|
body.dark .ant-input-number:focus {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TextArea Dark Mode Styling */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input,
|
||||||
|
body.dark-mode .ant-input,
|
||||||
|
body.dark textarea.ant-input {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input:focus,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input:focus,
|
||||||
|
body.dark-mode .ant-input:focus,
|
||||||
|
body.dark textarea.ant-input:focus {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder Text for Inputs */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input::placeholder,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-input-number-input::placeholder,
|
||||||
|
html[data-layout-mode="dark_mode"] textarea.ant-input::placeholder,
|
||||||
|
body.dark-mode .ant-input::placeholder,
|
||||||
|
body.dark .ant-input::placeholder {
|
||||||
|
color: #888888 !important;
|
||||||
|
}
|
||||||
border-color: #d9d9d9 !important;
|
border-color: #d9d9d9 !important;
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
@ -334,176 +274,224 @@ const EditWeddingGuest = () => {
|
|||||||
<div className="page-header">
|
<div className="page-header">
|
||||||
<div className="add-item d-flex">
|
<div className="add-item d-flex">
|
||||||
<div className="page-title">
|
<div className="page-title">
|
||||||
<h4>
|
<h4>Chỉnh sửa khách mời đám cưới</h4>
|
||||||
<Heart size={20} style={{ marginRight: '8px', color: '#ff69b4' }} />
|
<h6>Cập nhật thông tin khách mời cho đám cưới</h6>
|
||||||
Chỉnh sửa khách mời đám cưới
|
|
||||||
</h4>
|
|
||||||
<h6>Cập nhật thông tin khách mời</h6>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="page-btn">
|
<div className="page-btn">
|
||||||
<Link to="/wedding-guest-list">
|
<Link to="/wedding-guest-list" className="btn btn-added">
|
||||||
<Button
|
<ArrowLeft className="me-2" size={16} />
|
||||||
type="default"
|
Quay lại danh sách
|
||||||
icon={<ArrowLeft size={16} />}
|
|
||||||
>
|
|
||||||
Quay lại
|
|
||||||
</Button>
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Form */}
|
{/* Form */}
|
||||||
<Card
|
<div className="card">
|
||||||
className="wedding-guest-form"
|
<div className="card-body">
|
||||||
style={{
|
<Form
|
||||||
backgroundColor: isDarkTheme ? '#141432' : '#FAFBFE',
|
form={form}
|
||||||
borderColor: isDarkTheme ? '#434343' : '#d9d9d9',
|
layout="vertical"
|
||||||
color: isDarkTheme ? '#ffffff' : '#000000',
|
onFinish={handleSubmit}
|
||||||
background: isDarkTheme ? '#141432' : '#FAFBFE'
|
autoComplete="off"
|
||||||
}}
|
>
|
||||||
>
|
<div className="row">
|
||||||
<Form
|
{/* Guest Basic Info */}
|
||||||
form={form}
|
<div className="col-lg-12">
|
||||||
layout="vertical"
|
<div className="form-group-header">
|
||||||
onFinish={handleSubmit}
|
<div className="form-group-icon">
|
||||||
autoComplete="off"
|
<FileText size={20} />
|
||||||
className="wedding-guest-form"
|
</div>
|
||||||
>
|
<h5>Thông tin khách mời</h5>
|
||||||
<Row gutter={24}>
|
</div>
|
||||||
<Col xs={24} sm={12}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Tên khách mời</span>}
|
|
||||||
name="name"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Vui lòng nhập tên khách mời!' },
|
|
||||||
{ min: 2, message: 'Tên phải có ít nhất 2 ký tự!' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input placeholder="Nhập tên khách mời" style={getInputStyle()} />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={12}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Đơn vị</span>}
|
|
||||||
name="unit"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng nhập đơn vị!' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="Nhập đơn vị" style={getInputStyle()} />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Số người</span>}
|
|
||||||
name="numberOfPeople"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Vui lòng nhập số người!' },
|
|
||||||
{ type: 'number', min: 1, message: 'Số người phải lớn hơn 0!' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
placeholder="Nhập số người"
|
|
||||||
style={{ width: '100%', ...getInputStyle() }}
|
|
||||||
min={1}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Số tiền mừng (VND)</span>}
|
|
||||||
name="giftAmount"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Vui lòng nhập số tiền mừng!' },
|
|
||||||
{ type: 'number', min: 0, message: 'Số tiền phải lớn hơn hoặc bằng 0!' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
placeholder="Nhập số tiền mừng"
|
|
||||||
style={{ width: '100%', ...getInputStyle() }}
|
|
||||||
min={0}
|
|
||||||
formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
|
||||||
parser={value => value.replace(/\$\s?|(,*)/g, '')}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col xs={24} sm={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Trạng thái</span>}
|
|
||||||
name="status"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng chọn trạng thái!' }]}
|
|
||||||
>
|
|
||||||
<Select placeholder="Chọn trạng thái" style={getInputStyle()}>
|
|
||||||
<Option value="Going">✅ Đi</Option>
|
|
||||||
<Option value="NotGoing">❌ Không đi</Option>
|
|
||||||
<Option value="Pending">⏳ Chưa xác nhận</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24} sm={12}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Mối quan hệ</span>}
|
|
||||||
name="relationship"
|
|
||||||
rules={[{ required: true, message: 'Vui lòng chọn mối quan hệ!' }]}
|
|
||||||
>
|
|
||||||
<Select placeholder="Chọn mối quan hệ" style={getInputStyle()}>
|
|
||||||
<Option value="Family">👨👩👧👦 Gia đình</Option>
|
|
||||||
<Option value="Friend">👫 Bạn bè</Option>
|
|
||||||
<Option value="Colleague">💼 Đồng nghiệp</Option>
|
|
||||||
<Option value="Relative">👥 Họ hàng</Option>
|
|
||||||
<Option value="Other">🤝 Khác</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col xs={24}>
|
|
||||||
<Form.Item
|
|
||||||
label={<span style={getLabelStyle()}>Ghi chú</span>}
|
|
||||||
name="notes"
|
|
||||||
>
|
|
||||||
<TextArea
|
|
||||||
placeholder="Nhập ghi chú (tùy chọn)"
|
|
||||||
rows={4}
|
|
||||||
maxLength={500}
|
|
||||||
showCount
|
|
||||||
style={getInputStyle()}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row>
|
|
||||||
<Col xs={24}>
|
|
||||||
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end' }}>
|
|
||||||
<Link to="/wedding-guest-list">
|
|
||||||
<Button type="default">
|
|
||||||
Hủy
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
htmlType="submit"
|
|
||||||
loading={submitting}
|
|
||||||
icon={<Save size={16} />}
|
|
||||||
style={{ backgroundColor: '#ff69b4', borderColor: '#ff69b4' }}
|
|
||||||
>
|
|
||||||
Cập nhật khách mời
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
|
||||||
</Row>
|
<div className="col-lg-6">
|
||||||
</Form>
|
<div className="mb-3">
|
||||||
</Card>
|
<label className="form-label">Tên khách mời <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="name"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập tên khách mời!' },
|
||||||
|
{ min: 2, message: 'Tên phải có ít nhất 2 ký tự!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Nhập tên khách mời"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-6">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Đơn vị <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="unit"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng nhập đơn vị!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Nhập đơn vị"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
{/* Guest Details */}
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group-header">
|
||||||
|
<div className="form-group-icon">
|
||||||
|
<Users size={20} />
|
||||||
|
</div>
|
||||||
|
<h5>Chi tiết khách mời</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Số người <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="numberOfPeople"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập số người!' },
|
||||||
|
{ type: 'number', min: 1, message: 'Số người phải lớn hơn 0!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
placeholder="Nhập số người"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
min={1}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Số tiền mừng (VND) <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="giftAmount"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: 'Vui lòng nhập số tiền mừng!' },
|
||||||
|
{ type: 'number', min: 0, message: 'Số tiền phải lớn hơn hoặc bằng 0!' }
|
||||||
|
]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
placeholder="Nhập số tiền mừng"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
min={0}
|
||||||
|
formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
||||||
|
parser={value => value.replace(/\$\s?|(,*)/g, '')}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Trạng thái <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="status"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng chọn trạng thái!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="Chọn trạng thái"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<Option value="Confirmed">✅ Đã xác nhận</Option>
|
||||||
|
<Option value="Pending">⏳ Chưa xác nhận</Option>
|
||||||
|
<Option value="Cancelled">❌ Hủy</Option>
|
||||||
|
<Option value="Attended">👥 Đã tham dự</Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
{/* Additional Info */}
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="form-group-header">
|
||||||
|
<div className="form-group-icon">
|
||||||
|
<Gift size={20} />
|
||||||
|
</div>
|
||||||
|
<h5>Thông tin bổ sung</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-6">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Mối quan hệ <span className="text-danger">*</span></label>
|
||||||
|
<Form.Item
|
||||||
|
name="relationship"
|
||||||
|
rules={[{ required: true, message: 'Vui lòng chọn mối quan hệ!' }]}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="Chọn mối quan hệ"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<Option value="Family">👨👩👧👦 Gia đình</Option>
|
||||||
|
<Option value="Friend">👫 Bạn bè</Option>
|
||||||
|
<Option value="Colleague">💼 Đồng nghiệp</Option>
|
||||||
|
<Option value="Relative">👥 Họ hàng</Option>
|
||||||
|
<Option value="Other">🤝 Khác</Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Ghi chú</label>
|
||||||
|
<Form.Item
|
||||||
|
name="notes"
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
placeholder="Nhập ghi chú (tùy chọn)"
|
||||||
|
rows={4}
|
||||||
|
maxLength={500}
|
||||||
|
showCount
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Submit Buttons */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="btn-addproduct mb-4 d-flex align-items-center gap-3">
|
||||||
|
<LoadingButton
|
||||||
|
type="submit"
|
||||||
|
variant="primary"
|
||||||
|
size="medium"
|
||||||
|
loading={submitting}
|
||||||
|
loadingText="Đang cập nhật khách mời..."
|
||||||
|
className="create-project-btn"
|
||||||
|
icon={<Save size={16} />}
|
||||||
|
>
|
||||||
|
Cập nhật khách mời
|
||||||
|
</LoadingButton>
|
||||||
|
|
||||||
|
<Link to="/wedding-guest-list" className="btn btn-cancel btn-cancel-project">
|
||||||
|
Hủy
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -571,33 +571,44 @@ const WeddingGuestList = () => {
|
|||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
width: 100,
|
width: 120,
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<div className="action-table-data">
|
<div className="d-flex gap-2">
|
||||||
<div className="edit-delete-action">
|
<Link to={`/edit-wedding-guest/${record.id}`}>
|
||||||
<Link to={`/edit-wedding-guest/${record.id}`}>
|
<button
|
||||||
<Edit
|
className="btn btn-sm btn-outline-warning"
|
||||||
size={16}
|
title="Chỉnh sửa"
|
||||||
style={{
|
style={{
|
||||||
cursor: 'pointer',
|
border: '1px solid #faad14',
|
||||||
color: isDarkTheme ? '#ffffff' : '#666666',
|
color: '#faad14',
|
||||||
marginRight: '8px',
|
backgroundColor: 'transparent',
|
||||||
transition: 'color 0.2s ease'
|
padding: '4px 8px',
|
||||||
}}
|
borderRadius: '4px',
|
||||||
onMouseEnter={(e) => {
|
display: 'flex',
|
||||||
e.target.style.color = isDarkTheme ? '#cccccc' : '#333333';
|
alignItems: 'center',
|
||||||
}}
|
justifyContent: 'center'
|
||||||
onMouseLeave={(e) => {
|
}}
|
||||||
e.target.style.color = isDarkTheme ? '#ffffff' : '#666666';
|
>
|
||||||
}}
|
<Edit size={14} />
|
||||||
/>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<Trash2
|
<button
|
||||||
size={16}
|
className="btn btn-sm btn-outline-danger"
|
||||||
style={{ cursor: 'pointer', color: '#ff4d4f' }}
|
onClick={() => handleDeleteGuest(record.id)}
|
||||||
onClick={() => handleDeleteGuest(record.id)}
|
title="Xóa"
|
||||||
/>
|
style={{
|
||||||
</div>
|
border: '1px solid #ff4d4f',
|
||||||
|
color: '#ff4d4f',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: '4px 8px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash2 size={14} />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -716,34 +727,186 @@ const WeddingGuestList = () => {
|
|||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Edit button styling - remove blue hover */
|
/* Project Tracker Style Buttons */
|
||||||
.action-table-data .edit-delete-action a {
|
.btn-outline-warning {
|
||||||
text-decoration: none !important;
|
border: 1px solid #faad14 !important;
|
||||||
}
|
color: #faad14 !important;
|
||||||
|
|
||||||
.action-table-data .edit-delete-action a:hover {
|
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
color: inherit !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-table-data .edit-delete-action svg {
|
.btn-outline-warning:hover {
|
||||||
transition: color 0.2s ease !important;
|
background-color: #faad14 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
border-color: #faad14 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-table-data .edit-delete-action svg:hover {
|
.btn-outline-danger {
|
||||||
color: ${isDarkTheme ? '#cccccc' : '#333333'} !important;
|
border: 1px solid #ff4d4f !important;
|
||||||
}
|
color: #ff4d4f !important;
|
||||||
|
|
||||||
/* Remove any blue hover effects from links */
|
|
||||||
a:hover {
|
|
||||||
color: inherit !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ant Design link hover override */
|
|
||||||
.ant-table-tbody > tr > td a:hover {
|
|
||||||
color: inherit !important;
|
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-outline-danger:hover {
|
||||||
|
background-color: #ff4d4f !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
border-color: #ff4d4f !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode button adjustments */
|
||||||
|
[data-layout-mode="dark_mode"] .btn-outline-warning {
|
||||||
|
border-color: #faad14 !important;
|
||||||
|
color: #faad14 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-layout-mode="dark_mode"] .btn-outline-danger {
|
||||||
|
border-color: #ff4d4f !important;
|
||||||
|
color: #ff4d4f !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove background-color from wedding guest search inputs */
|
||||||
|
.wedding-guest-search-input input,
|
||||||
|
.wedding-guest-search-input .ant-input {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure search input transparency in all themes */
|
||||||
|
.wedding-guest-search-input .ant-input:focus,
|
||||||
|
.wedding-guest-search-input .ant-input:hover,
|
||||||
|
.wedding-guest-search-input input:focus,
|
||||||
|
.wedding-guest-search-input input:hover {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown Lists Dark Theme Styling */
|
||||||
|
|
||||||
|
/* Light Mode Dropdown Styling */
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-selector,
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-single .ant-select-selector,
|
||||||
|
body.light-mode .ant-select-selector,
|
||||||
|
body.light .ant-select-selector {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-color: #d9d9d9 !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-dropdown,
|
||||||
|
body.light-mode .ant-select-dropdown,
|
||||||
|
body.light .ant-select-dropdown {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-color: #d9d9d9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-item,
|
||||||
|
body.light-mode .ant-select-item,
|
||||||
|
body.light .ant-select-item {
|
||||||
|
color: #000000 !important;
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-item:hover,
|
||||||
|
body.light-mode .ant-select-item:hover,
|
||||||
|
body.light .ant-select-item:hover {
|
||||||
|
background-color: #f5f5f5 !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="light_mode"] .ant-select-item-option-selected,
|
||||||
|
body.light-mode .ant-select-item-option-selected,
|
||||||
|
body.light .ant-select-item-option-selected {
|
||||||
|
background-color: #1890ff !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark Mode Dropdown Styling */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-selector,
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-single .ant-select-selector,
|
||||||
|
body.dark-mode .ant-select-selector,
|
||||||
|
body.dark .ant-select-selector {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-dropdown,
|
||||||
|
body.dark-mode .ant-select-dropdown,
|
||||||
|
body.dark .ant-select-dropdown {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #434343 !important;
|
||||||
|
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 9px 28px 8px rgba(0, 0, 0, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item,
|
||||||
|
body.dark-mode .ant-select-item,
|
||||||
|
body.dark .ant-select-item {
|
||||||
|
color: #ffffff !important;
|
||||||
|
background-color: #141432 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item:hover,
|
||||||
|
body.dark-mode .ant-select-item:hover,
|
||||||
|
body.dark .ant-select-item:hover {
|
||||||
|
background-color: #434343 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-item-option-selected,
|
||||||
|
body.dark-mode .ant-select-item-option-selected,
|
||||||
|
body.dark .ant-select-item-option-selected {
|
||||||
|
background-color: #177ddc !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown Arrow Icon Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-arrow,
|
||||||
|
body.dark-mode .ant-select-arrow,
|
||||||
|
body.dark .ant-select-arrow {
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus States for Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-focused .ant-select-selector,
|
||||||
|
body.dark-mode .ant-select-focused .ant-select-selector,
|
||||||
|
body.dark .ant-select-focused .ant-select-selector {
|
||||||
|
background-color: #141432 !important;
|
||||||
|
border-color: #177ddc !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(23, 125, 220, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder Text Dark Mode */
|
||||||
|
html[data-layout-mode="dark_mode"] .ant-select-selection-placeholder,
|
||||||
|
body.dark-mode .ant-select-selection-placeholder,
|
||||||
|
body.dark .ant-select-selection-placeholder {
|
||||||
|
color: #888888 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dynamic Theme Support */
|
||||||
|
.ant-select-selector {
|
||||||
|
background-color: ${isDarkTheme ? '#141432' : '#ffffff'} !important;
|
||||||
|
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
||||||
|
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-dropdown {
|
||||||
|
background-color: ${isDarkTheme ? '#141432' : '#ffffff'} !important;
|
||||||
|
border-color: ${isDarkTheme ? '#434343' : '#d9d9d9'} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-item {
|
||||||
|
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
||||||
|
background-color: ${isDarkTheme ? '#141432' : '#ffffff'} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-item:hover {
|
||||||
|
background-color: ${isDarkTheme ? '#434343' : '#f5f5f5'} !important;
|
||||||
|
color: ${isDarkTheme ? '#ffffff' : '#000000'} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-item-option-selected {
|
||||||
|
background-color: ${isDarkTheme ? '#177ddc' : '#1890ff'} !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
@ -773,9 +936,8 @@ const WeddingGuestList = () => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
icon={<Plus size={16} />}
|
icon={<Plus size={16} />}
|
||||||
className="btn btn-added"
|
className="btn btn-added"
|
||||||
style={{ backgroundColor: '#ff69b4', borderColor: '#ff69b4' }}
|
|
||||||
>
|
>
|
||||||
Thêm khách mời
|
Thêm mới
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -835,6 +997,11 @@ const WeddingGuestList = () => {
|
|||||||
<div className="card-body pb-0">
|
<div className="card-body pb-0">
|
||||||
<div className="table-top">
|
<div className="table-top">
|
||||||
<div className="search-set">
|
<div className="search-set">
|
||||||
|
<div className="search-input">
|
||||||
|
<span style={{ fontSize: '16px', fontWeight: '500' }}>
|
||||||
|
Danh sách khách mời
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div className="search-input">
|
<div className="search-input">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Tìm kiếm khách mời..."
|
placeholder="Tìm kiếm khách mời..."
|
||||||
@ -843,8 +1010,6 @@ const WeddingGuestList = () => {
|
|||||||
onChange={(e) => handleSearch(e.target.value)}
|
onChange={(e) => handleSearch(e.target.value)}
|
||||||
style={{
|
style={{
|
||||||
width: 300,
|
width: 300,
|
||||||
color: '#000000 !important',
|
|
||||||
backgroundColor: '#ffffff',
|
|
||||||
border: '1px solid #d9d9d9'
|
border: '1px solid #d9d9d9'
|
||||||
}}
|
}}
|
||||||
className="wedding-guest-search-input"
|
className="wedding-guest-search-input"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user