mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 08:03:13 +00:00
fix
This commit is contained in:
parent
ff2eacaba4
commit
3f3dcc70f6
6 changed files with 244 additions and 128 deletions
|
|
@ -305,3 +305,57 @@ body {
|
|||
.contactTable tbody tr:nth-child(even) {
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
.controlsTop {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.leftControls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter select {
|
||||
height: 34px;
|
||||
border: 1px solid #ccc;
|
||||
border-right: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
padding: 6px 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.filter input {
|
||||
height: 34px;
|
||||
width: 260px;
|
||||
border: 1px solid #ccc;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.searchBtn {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #0073aa;
|
||||
background-color: #0073aa;
|
||||
color: #fff;
|
||||
border-radius: 0 4px 4px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.searchBtn:hover {
|
||||
background-color: #005f8d;
|
||||
}
|
||||
|
||||
.rightControls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +1,100 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { fetchAccountsPaged, deleteAccount } from "./api";
|
||||
import { useNavigate } from "react-router";
|
||||
import "./styles.css";
|
||||
|
||||
export default function AccountList() {
|
||||
const [data, setData] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
const [rows, setRows] = useState([]);
|
||||
const [search, setSearch] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
const res = await fetchAccountsPaged({ search });
|
||||
setRows(res?.rows ?? []);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, []);
|
||||
}, [search]);
|
||||
|
||||
const load = async () => {
|
||||
const res = await fetchAccountsPaged({});
|
||||
setData(res.rows);
|
||||
const handleDelete = async (id) => {
|
||||
if (!window.confirm("Delete this account?")) return;
|
||||
await deleteAccount(id);
|
||||
load();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Accounts</h2>
|
||||
<section className="contactsPage">
|
||||
<div className="pageTitle">Accounts</div>
|
||||
|
||||
<button onClick={() => (window.location.href = "/accounts/new")}>
|
||||
+ Add Account
|
||||
</button>
|
||||
<div className="card controlsCard">
|
||||
<div className="controlsTop">
|
||||
<div className="leftControls">
|
||||
<div className="filter">
|
||||
<input
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder="Enter search criteria here..."
|
||||
/>
|
||||
<button className="searchBtn">Search!</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Industry</th>
|
||||
<th>Phone</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<div className="rightControls">
|
||||
<button
|
||||
className="iconSmall"
|
||||
title="New Account"
|
||||
onClick={() => navigate("/accounts/new")}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tbody>
|
||||
{data.map((x) => (
|
||||
<tr key={x.id}>
|
||||
<td>{x.name}</td>
|
||||
<td>{x.industry}</td>
|
||||
<td>{x.phone}</td>
|
||||
<td>
|
||||
<button onClick={() => (window.location.href = `/accounts/${x.id}/edit`)}>
|
||||
Edit
|
||||
</button>
|
||||
<button onClick={() => deleteAccount(x.id)}>Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{loading ? (
|
||||
<div style={{ padding: 12 }}>Loading accounts...</div>
|
||||
) : (
|
||||
<table className="contactTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Industry</th>
|
||||
<th>Phone</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{rows.map((x) => (
|
||||
<tr key={x.id}>
|
||||
<td>{x.name}</td>
|
||||
<td>{x.industry}</td>
|
||||
<td>{x.phoneNumber}</td>
|
||||
<td className="iconActions">
|
||||
<button
|
||||
className="iconBtn"
|
||||
title="Edit"
|
||||
onClick={() => navigate(`/accounts/${x.id}/edit`)}
|
||||
>
|
||||
✏️
|
||||
</button>
|
||||
<button
|
||||
className="iconBtnDanger"
|
||||
title="Delete"
|
||||
onClick={() => handleDelete(x.id)}
|
||||
>
|
||||
🗑
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,23 +12,25 @@ export const fetchAccountsPaged = async ({
|
|||
)}&page=${page}&pageSize=${pageSize}`
|
||||
);
|
||||
|
||||
const rows = (res?.data || res?.Data || []).map((x) => ({
|
||||
id: x.Id,
|
||||
name: x.Name ?? x.AccountName ?? "",
|
||||
number: x.AccountNumber ?? "",
|
||||
industry: x.Industry ?? "",
|
||||
website: x.Website ?? "",
|
||||
primaryContact: x.PrimaryContact ?? "",
|
||||
phoneNumber: x.Phone ?? x.PhoneNumber ?? "",
|
||||
owner: x.Owner ?? "",
|
||||
const data = res?.data || res?.Data || [];
|
||||
|
||||
const rows = data.map((x) => ({
|
||||
id: x.id ?? x.Id,
|
||||
name: x.name ?? x.Name ?? x.AccountName ?? "",
|
||||
number: x.number ?? x.AccountNumber ?? "",
|
||||
industry: x.industry ?? x.Industry ?? "",
|
||||
website: x.website ?? x.Website ?? "",
|
||||
primaryContact: x.primaryContact ?? x.PrimaryContact ?? "",
|
||||
phoneNumber: x.phoneNumber ?? x.Phone ?? x.PhoneNumber ?? "",
|
||||
owner: x.owner ?? x.Owner ?? "",
|
||||
}));
|
||||
|
||||
return {
|
||||
rows,
|
||||
page: res?.PageNumber ?? 1,
|
||||
pageSize: res?.PageSize ?? pageSize,
|
||||
totalCount: res?.TotalCount ?? rows.length,
|
||||
totalPages: res?.TotalPages ?? 1,
|
||||
page: res?.page ?? res?.PageNumber ?? page,
|
||||
pageSize: res?.pageSize ?? res?.PageSize ?? pageSize,
|
||||
totalCount: res?.totalCount ?? res?.TotalCount ?? rows.length,
|
||||
totalPages: res?.totalPages ?? res?.TotalPages ?? 1,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ import { API_URL } from '../../../constants';
|
|||
export const fetchContactsPaged = async ({ search = "", page = 1, pageSize = 12 }) => {
|
||||
const res = await get(`${API_URL}/Contact/GetContactList?search=${encodeURIComponent(search)}&page=${page}&pageSize=${pageSize}`);
|
||||
const rows = (res?.data || res?.Data || []).map(x => ({
|
||||
id: x.Id,
|
||||
name: x.Name,
|
||||
account: x.Account ?? "",
|
||||
title: x.Title ?? "",
|
||||
email: x.email ?? x.Email ?? "",
|
||||
phoneNumber: x.phone ?? x.PhoneNumber ?? "",
|
||||
owner: x.Owner ?? "",
|
||||
id: x.id,
|
||||
name: x.name,
|
||||
account: x.account ?? "",
|
||||
title: x.title ?? "",
|
||||
email: x.email ?? "",
|
||||
phoneNumber: x.phone ?? "",
|
||||
owner: x.owner ?? "",
|
||||
}));
|
||||
return {
|
||||
rows,
|
||||
page: res?.PageNumber ?? 1,
|
||||
pageSize: res?.PageSize ?? pageSize,
|
||||
totalCount: res?.TotalCount ?? rows.length,
|
||||
totalPages: res?.TotalPages ?? 1,
|
||||
page: res?.pageNumber ?? 1,
|
||||
pageSize: res?.pageSize ?? pageSize,
|
||||
totalCount: res?.totalCount ?? rows.length,
|
||||
totalPages: res?.totalPages ?? 1,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { fetchEmployeesPaged, deleteEmployee } from "./api";
|
||||
import { useNavigate } from "react-router";
|
||||
import { toast } from "react-toastify";
|
||||
import "./styles.css";
|
||||
|
||||
export default function EmployeeList() {
|
||||
const navigate = useNavigate();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [rows, setRows] = useState([]);
|
||||
const [search, setSearch] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
const res = await fetchEmployeesPaged({ search });
|
||||
setRows(res.rows);
|
||||
setRows(res?.rows ?? []);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
|
|
@ -23,70 +23,82 @@ export default function EmployeeList() {
|
|||
const handleDelete = async (id) => {
|
||||
if (!window.confirm("Delete this employee?")) return;
|
||||
await deleteEmployee(id);
|
||||
toast.success("Employee deleted");
|
||||
load();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<div className="pageHeader">
|
||||
<h2>Employees</h2>
|
||||
<button onClick={() => navigate("/employees/new")} className="btnPrimary">
|
||||
+ New Employee
|
||||
</button>
|
||||
</div>
|
||||
<section className="contactsPage">
|
||||
<div className="pageTitle">Employees</div>
|
||||
|
||||
<input
|
||||
className="searchBoxList"
|
||||
placeholder="Search employees..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
<div className="card controlsCard">
|
||||
<div className="controlsTop">
|
||||
<div className="leftControls">
|
||||
<div className="filter">
|
||||
<input
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder="Enter search criteria here..."
|
||||
/>
|
||||
<button className="searchBtn">Search!</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<p>Loading employees...</p>
|
||||
) : (
|
||||
<table className="dataTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Job Title</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th>Department</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<div className="rightControls">
|
||||
<button
|
||||
className="iconSmall"
|
||||
title="New Employee"
|
||||
onClick={() => navigate("/employees/new")}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tbody>
|
||||
{rows.map((r) => (
|
||||
<tr key={r.id}>
|
||||
<td>{r.name}</td>
|
||||
<td>{r.jobTitle}</td>
|
||||
<td>{r.email}</td>
|
||||
<td>{r.phone}</td>
|
||||
<td>{r.department}</td>
|
||||
<td>{r.status}</td>
|
||||
<td>
|
||||
<button
|
||||
className="btnSmall"
|
||||
onClick={() => navigate(`/employees/${r.id}`)}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
className="btnSmallDanger"
|
||||
onClick={() => handleDelete(r.id)}
|
||||
>
|
||||
Del
|
||||
</button>
|
||||
</td>
|
||||
{loading ? (
|
||||
<div style={{ padding: 12 }}>Loading employees...</div>
|
||||
) : (
|
||||
<table className="contactTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Job Title</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{rows.map((r) => (
|
||||
<tr key={r.id}>
|
||||
<td>{r.name}</td>
|
||||
<td>{r.jobTitle}</td>
|
||||
<td>{r.email}</td>
|
||||
<td>{r.phone}</td>
|
||||
<td>{r.status}</td>
|
||||
<td className="iconActions">
|
||||
<button
|
||||
className="iconBtn"
|
||||
title="Edit"
|
||||
onClick={() => navigate(`/employees/${r.id}`)}
|
||||
>
|
||||
✏️
|
||||
</button>
|
||||
<button
|
||||
className="iconBtnDanger"
|
||||
title="Delete"
|
||||
onClick={() => handleDelete(r.id)}
|
||||
>
|
||||
🗑
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ export const fetchEmployeesPaged = async ({
|
|||
)}&page=${page}&pageSize=${pageSize}`
|
||||
);
|
||||
|
||||
const rows = (res?.data || res?.Data || []).map((x) => ({
|
||||
id: x.Id,
|
||||
name: `${x.FirstName ?? ""} ${x.LastName ?? ""}`.trim(),
|
||||
jobTitle: x.JobTitle ?? "",
|
||||
email: x.Email ?? "",
|
||||
phone: x.Phone ?? "",
|
||||
department: x.Department ?? "",
|
||||
status: x.Status ?? "",
|
||||
const rows = (res || []).map((x) => ({
|
||||
id: x.id,
|
||||
name: `${x.name ?? ""} ${x.name ?? ""}`.trim(),
|
||||
jobTitle: x.jobTitle ?? "",
|
||||
email: x.email ?? "",
|
||||
phone: x.phone ?? "",
|
||||
department: x.department ?? "",
|
||||
status: x.status ?? "",
|
||||
}));
|
||||
|
||||
return {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue