feat: add date range filter to Occupancies, status filter to Tenants
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import api from '../../api';
|
import api from '../../api';
|
||||||
import PermissionButton from '../../components/PermissionButton';
|
import PermissionButton from '../../components/PermissionButton';
|
||||||
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
const OccupanciesPage: React.FC = () => {
|
const OccupanciesPage: React.FC = () => {
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [data, setData] = useState<any[]>([]);
|
||||||
@@ -43,8 +44,9 @@ const OccupanciesPage: React.FC = () => {
|
|||||||
const [autoDeposit, setAutoDeposit] = useState(true);
|
const [autoDeposit, setAutoDeposit] = useState(true);
|
||||||
const [depositAmount, setDepositAmount] = useState(500);
|
const [depositAmount, setDepositAmount] = useState(500);
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
|
const [dateRange, setDateRange] = useState<[dayjs.Dayjs | null, dayjs.Dayjs | null] | null>(null);
|
||||||
const [batchCheckOutModal, setBatchCheckOutModal] = useState(false);
|
const [batchCheckOutModal, setBatchCheckOutModal] = useState(false);
|
||||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
|
||||||
const [checkInForm] = Form.useForm();
|
const [checkInForm] = Form.useForm();
|
||||||
const [checkOutForm] = Form.useForm();
|
const [checkOutForm] = Form.useForm();
|
||||||
const [transferForm] = Form.useForm();
|
const [transferForm] = Form.useForm();
|
||||||
@@ -54,7 +56,7 @@ const OccupanciesPage: React.FC = () => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const [occ, stu, rm, tn]: any[] = await Promise.all([
|
const [occ, stu, rm, tn]: any[] = await Promise.all([
|
||||||
api.get('/occupancies', { params: { active: showActive ? 'true' : undefined } }),
|
api.get('/occupancies', { params: { active: showActive ? 'true' : undefined, dateFrom: dateRange?.[0]?.format('YYYY-MM-DD'), dateTo: dateRange?.[1]?.format('YYYY-MM-DD') } }),
|
||||||
api.get('/students'),
|
api.get('/students'),
|
||||||
api.get('/rooms/overview'),
|
api.get('/rooms/overview'),
|
||||||
api.get('/tenants'),
|
api.get('/tenants'),
|
||||||
@@ -72,7 +74,7 @@ const OccupanciesPage: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
setSelectedRowKeys([]);
|
setSelectedRowKeys([]);
|
||||||
}, [showActive]);
|
}, [showActive, dateRange]);
|
||||||
|
|
||||||
const filteredData = useMemo(() => {
|
const filteredData = useMemo(() => {
|
||||||
if (!searchText) return data;
|
if (!searchText) return data;
|
||||||
@@ -275,6 +277,7 @@ const OccupanciesPage: React.FC = () => {
|
|||||||
allowClear
|
allowClear
|
||||||
style={{ width: 200 }}
|
style={{ width: 200 }}
|
||||||
/>
|
/>
|
||||||
|
<RangePicker value={dateRange} onChange={(dates) => { setDateRange(dates ? [dates[0], dates[1]] : null); }} placeholder={['入住开始', '入住结束']} style={{ width: 240 }} />
|
||||||
</Space>
|
</Space>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState, useMemo } from 'react';
|
import React, { useEffect, useState, useMemo } from 'react';
|
||||||
import { Table, Modal, Form, Input, Space, message, Tag, Popconfirm } from 'antd';
|
import { Table, Modal, Form, Input, Select, Space, message, Tag, Popconfirm } from 'antd';
|
||||||
import { PlusOutlined, InboxOutlined } from '@ant-design/icons';
|
import { PlusOutlined, InboxOutlined } from '@ant-design/icons';
|
||||||
import api from '../../api';
|
import api from '../../api';
|
||||||
import PermissionButton from '../../components/PermissionButton';
|
import PermissionButton from '../../components/PermissionButton';
|
||||||
@@ -24,14 +24,19 @@ const TenantsPage: React.FC = () => {
|
|||||||
const [editing, setEditing] = useState<any>(null);
|
const [editing, setEditing] = useState<any>(null);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
const [filterStatus, setFilterStatus] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const filteredData = useMemo(() => {
|
const filteredData = useMemo(() => {
|
||||||
if (!searchText) return data;
|
let result = data;
|
||||||
|
if (searchText) {
|
||||||
const s = searchText.toLowerCase();
|
const s = searchText.toLowerCase();
|
||||||
return data.filter(
|
result = result.filter((d: Record<string, unknown>) =>
|
||||||
(d: any) => d.name?.toLowerCase().includes(s) || d.contact?.toLowerCase().includes(s),
|
(typeof d.name === 'string' && d.name.toLowerCase().includes(s)) ||
|
||||||
);
|
(typeof d.contact === 'string' && d.contact.toLowerCase().includes(s)));
|
||||||
}, [data, searchText]);
|
}
|
||||||
|
if (filterStatus) result = result.filter((d: Record<string, unknown>) => d.status === filterStatus);
|
||||||
|
return result;
|
||||||
|
}, [data, searchText, filterStatus]);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -165,6 +170,8 @@ const TenantsPage: React.FC = () => {
|
|||||||
if (!e.target.value) setSearchText('');
|
if (!e.target.value) setSearchText('');
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Select placeholder="状态" allowClear style={{ width: 110 }} value={filterStatus} onChange={setFilterStatus}
|
||||||
|
options={[{value:'active',label:'活跃'},{value:'archived',label:'已归档'}]} />
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
permission="tenant:create"
|
permission="tenant:create"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|||||||
Reference in New Issue
Block a user