mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-06 13:32:06 +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) {
|
.contactTable tbody tr:nth-child(even) {
|
||||||
background: #fbfbfb;
|
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 React, { useEffect, useState } from "react";
|
||||||
import { fetchAccountsPaged, deleteAccount } from "./api";
|
import { fetchAccountsPaged, deleteAccount } from "./api";
|
||||||
|
import { useNavigate } from "react-router";
|
||||||
|
import "./styles.css";
|
||||||
|
|
||||||
export default function AccountList() {
|
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(() => {
|
useEffect(() => {
|
||||||
load();
|
load();
|
||||||
}, []);
|
}, [search]);
|
||||||
|
|
||||||
const load = async () => {
|
const handleDelete = async (id) => {
|
||||||
const res = await fetchAccountsPaged({});
|
if (!window.confirm("Delete this account?")) return;
|
||||||
setData(res.rows);
|
await deleteAccount(id);
|
||||||
|
load();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<section className="contactsPage">
|
||||||
<h2>Accounts</h2>
|
<div className="pageTitle">Accounts</div>
|
||||||
|
|
||||||
<button onClick={() => (window.location.href = "/accounts/new")}>
|
<div className="card controlsCard">
|
||||||
+ Add Account
|
<div className="controlsTop">
|
||||||
</button>
|
<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">
|
<div className="rightControls">
|
||||||
<thead>
|
<button
|
||||||
<tr>
|
className="iconSmall"
|
||||||
<th>Name</th>
|
title="New Account"
|
||||||
<th>Industry</th>
|
onClick={() => navigate("/accounts/new")}
|
||||||
<th>Phone</th>
|
>
|
||||||
<th></th>
|
+
|
||||||
</tr>
|
</button>
|
||||||
</thead>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<tbody>
|
{loading ? (
|
||||||
{data.map((x) => (
|
<div style={{ padding: 12 }}>Loading accounts...</div>
|
||||||
<tr key={x.id}>
|
) : (
|
||||||
<td>{x.name}</td>
|
<table className="contactTable">
|
||||||
<td>{x.industry}</td>
|
<thead>
|
||||||
<td>{x.phone}</td>
|
<tr>
|
||||||
<td>
|
<th>Name</th>
|
||||||
<button onClick={() => (window.location.href = `/accounts/${x.id}/edit`)}>
|
<th>Industry</th>
|
||||||
Edit
|
<th>Phone</th>
|
||||||
</button>
|
<th></th>
|
||||||
<button onClick={() => deleteAccount(x.id)}>Delete</button>
|
</tr>
|
||||||
</td>
|
</thead>
|
||||||
</tr>
|
|
||||||
))}
|
<tbody>
|
||||||
</tbody>
|
{rows.map((x) => (
|
||||||
</table>
|
<tr key={x.id}>
|
||||||
</div>
|
<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}`
|
)}&page=${page}&pageSize=${pageSize}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const rows = (res?.data || res?.Data || []).map((x) => ({
|
const data = res?.data || res?.Data || [];
|
||||||
id: x.Id,
|
|
||||||
name: x.Name ?? x.AccountName ?? "",
|
const rows = data.map((x) => ({
|
||||||
number: x.AccountNumber ?? "",
|
id: x.id ?? x.Id,
|
||||||
industry: x.Industry ?? "",
|
name: x.name ?? x.Name ?? x.AccountName ?? "",
|
||||||
website: x.Website ?? "",
|
number: x.number ?? x.AccountNumber ?? "",
|
||||||
primaryContact: x.PrimaryContact ?? "",
|
industry: x.industry ?? x.Industry ?? "",
|
||||||
phoneNumber: x.Phone ?? x.PhoneNumber ?? "",
|
website: x.website ?? x.Website ?? "",
|
||||||
owner: x.Owner ?? "",
|
primaryContact: x.primaryContact ?? x.PrimaryContact ?? "",
|
||||||
|
phoneNumber: x.phoneNumber ?? x.Phone ?? x.PhoneNumber ?? "",
|
||||||
|
owner: x.owner ?? x.Owner ?? "",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rows,
|
rows,
|
||||||
page: res?.PageNumber ?? 1,
|
page: res?.page ?? res?.PageNumber ?? page,
|
||||||
pageSize: res?.PageSize ?? pageSize,
|
pageSize: res?.pageSize ?? res?.PageSize ?? pageSize,
|
||||||
totalCount: res?.TotalCount ?? rows.length,
|
totalCount: res?.totalCount ?? res?.TotalCount ?? rows.length,
|
||||||
totalPages: res?.TotalPages ?? 1,
|
totalPages: res?.totalPages ?? res?.TotalPages ?? 1,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,20 @@ import { API_URL } from '../../../constants';
|
||||||
export const fetchContactsPaged = async ({ search = "", page = 1, pageSize = 12 }) => {
|
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 res = await get(`${API_URL}/Contact/GetContactList?search=${encodeURIComponent(search)}&page=${page}&pageSize=${pageSize}`);
|
||||||
const rows = (res?.data || res?.Data || []).map(x => ({
|
const rows = (res?.data || res?.Data || []).map(x => ({
|
||||||
id: x.Id,
|
id: x.id,
|
||||||
name: x.Name,
|
name: x.name,
|
||||||
account: x.Account ?? "",
|
account: x.account ?? "",
|
||||||
title: x.Title ?? "",
|
title: x.title ?? "",
|
||||||
email: x.email ?? x.Email ?? "",
|
email: x.email ?? "",
|
||||||
phoneNumber: x.phone ?? x.PhoneNumber ?? "",
|
phoneNumber: x.phone ?? "",
|
||||||
owner: x.Owner ?? "",
|
owner: x.owner ?? "",
|
||||||
}));
|
}));
|
||||||
return {
|
return {
|
||||||
rows,
|
rows,
|
||||||
page: res?.PageNumber ?? 1,
|
page: res?.pageNumber ?? 1,
|
||||||
pageSize: res?.PageSize ?? pageSize,
|
pageSize: res?.pageSize ?? pageSize,
|
||||||
totalCount: res?.TotalCount ?? rows.length,
|
totalCount: res?.totalCount ?? rows.length,
|
||||||
totalPages: res?.TotalPages ?? 1,
|
totalPages: res?.totalPages ?? 1,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { fetchEmployeesPaged, deleteEmployee } from "./api";
|
import { fetchEmployeesPaged, deleteEmployee } from "./api";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { toast } from "react-toastify";
|
import "./styles.css";
|
||||||
|
|
||||||
export default function EmployeeList() {
|
export default function EmployeeList() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [rows, setRows] = useState([]);
|
const [rows, setRows] = useState([]);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await fetchEmployeesPaged({ search });
|
const res = await fetchEmployeesPaged({ search });
|
||||||
setRows(res.rows);
|
setRows(res?.rows ?? []);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -23,70 +23,82 @@ export default function EmployeeList() {
|
||||||
const handleDelete = async (id) => {
|
const handleDelete = async (id) => {
|
||||||
if (!window.confirm("Delete this employee?")) return;
|
if (!window.confirm("Delete this employee?")) return;
|
||||||
await deleteEmployee(id);
|
await deleteEmployee(id);
|
||||||
toast.success("Employee deleted");
|
|
||||||
load();
|
load();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pageWrapper">
|
<section className="contactsPage">
|
||||||
<div className="pageHeader">
|
<div className="pageTitle">Employees</div>
|
||||||
<h2>Employees</h2>
|
|
||||||
<button onClick={() => navigate("/employees/new")} className="btnPrimary">
|
|
||||||
+ New Employee
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input
|
<div className="card controlsCard">
|
||||||
className="searchBoxList"
|
<div className="controlsTop">
|
||||||
placeholder="Search employees..."
|
<div className="leftControls">
|
||||||
value={search}
|
<div className="filter">
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
<input
|
||||||
/>
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
placeholder="Enter search criteria here..."
|
||||||
|
/>
|
||||||
|
<button className="searchBtn">Search!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{loading ? (
|
<div className="rightControls">
|
||||||
<p>Loading employees...</p>
|
<button
|
||||||
) : (
|
className="iconSmall"
|
||||||
<table className="dataTable">
|
title="New Employee"
|
||||||
<thead>
|
onClick={() => navigate("/employees/new")}
|
||||||
<tr>
|
>
|
||||||
<th>Name</th>
|
+
|
||||||
<th>Job Title</th>
|
</button>
|
||||||
<th>Email</th>
|
</div>
|
||||||
<th>Phone</th>
|
</div>
|
||||||
<th>Department</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
{loading ? (
|
||||||
{rows.map((r) => (
|
<div style={{ padding: 12 }}>Loading employees...</div>
|
||||||
<tr key={r.id}>
|
) : (
|
||||||
<td>{r.name}</td>
|
<table className="contactTable">
|
||||||
<td>{r.jobTitle}</td>
|
<thead>
|
||||||
<td>{r.email}</td>
|
<tr>
|
||||||
<td>{r.phone}</td>
|
<th>Name</th>
|
||||||
<td>{r.department}</td>
|
<th>Job Title</th>
|
||||||
<td>{r.status}</td>
|
<th>Email</th>
|
||||||
<td>
|
<th>Phone</th>
|
||||||
<button
|
<th>Status</th>
|
||||||
className="btnSmall"
|
<th></th>
|
||||||
onClick={() => navigate(`/employees/${r.id}`)}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btnSmallDanger"
|
|
||||||
onClick={() => handleDelete(r.id)}
|
|
||||||
>
|
|
||||||
Del
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</thead>
|
||||||
</tbody>
|
|
||||||
</table>
|
<tbody>
|
||||||
)}
|
{rows.map((r) => (
|
||||||
</div>
|
<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}`
|
)}&page=${page}&pageSize=${pageSize}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const rows = (res?.data || res?.Data || []).map((x) => ({
|
const rows = (res || []).map((x) => ({
|
||||||
id: x.Id,
|
id: x.id,
|
||||||
name: `${x.FirstName ?? ""} ${x.LastName ?? ""}`.trim(),
|
name: `${x.name ?? ""} ${x.name ?? ""}`.trim(),
|
||||||
jobTitle: x.JobTitle ?? "",
|
jobTitle: x.jobTitle ?? "",
|
||||||
email: x.Email ?? "",
|
email: x.email ?? "",
|
||||||
phone: x.Phone ?? "",
|
phone: x.phone ?? "",
|
||||||
department: x.Department ?? "",
|
department: x.department ?? "",
|
||||||
status: x.Status ?? "",
|
status: x.status ?? "",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue