announcement sort fix
This commit is contained in:
parent
efdbe2377c
commit
9ba77afd6e
@ -27,6 +27,7 @@ import {
|
||||
cilLocationPin,
|
||||
cilSettings,
|
||||
cilMoney,
|
||||
cilBell,
|
||||
} from "@coreui/icons";
|
||||
import { CNavGroup, CNavItem, CNavTitle, CTabContent } from "@coreui/react";
|
||||
|
||||
@ -196,6 +197,13 @@ const _nav = [
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
component: CNavItem,
|
||||
name: "Announcement",
|
||||
icon: <CIcon icon={cilBell} customClassName="nav-icon" />,
|
||||
to: "/announcement",
|
||||
group: "Inventory",
|
||||
},
|
||||
{
|
||||
component: CNavGroup,
|
||||
name: "Settings",
|
||||
|
@ -15,9 +15,9 @@ import { cibGmail } from "@coreui/icons";
|
||||
import { createRoot } from "react-dom/client";
|
||||
|
||||
const setupAxios = () => {
|
||||
// axios.defaults.baseURL = "http://localhost:5000";
|
||||
axios.defaults.baseURL = "http://localhost:5000";
|
||||
// axios.defaults.baseURL = "https://cheminova-api-2.onrender.com";
|
||||
axios.defaults.baseURL = "https://api.cnapp.co.in";
|
||||
// axios.defaults.baseURL = "https://api.cnapp.co.in";
|
||||
|
||||
axios.defaults.headers = {
|
||||
"Cache-Control": "no-cache,no-store",
|
||||
|
@ -159,6 +159,8 @@ import DistributorStocks from "./views/RetailDistributors/DistributorStock";
|
||||
import AddMultiplerd from "./views/RetailDistributors/AddMultipleRD";
|
||||
import AddMultipletm from "./views/TerritoryManager/AddMultipleTM";
|
||||
import AddMultiplesc from "./views/SalesCoOrdinators/AddMultipleSC";
|
||||
import Announcements from "./views/Announcment/announcement";
|
||||
import CreateAnnouncement from "./views/Announcment/createAnnouncement";
|
||||
const routes = [
|
||||
//dashboard
|
||||
|
||||
@ -718,7 +720,19 @@ const routes = [
|
||||
navName: "Orders",
|
||||
},
|
||||
//-------------- End Order Management Routes---------------------------------------
|
||||
|
||||
// Announcement
|
||||
{
|
||||
path: "/announcement",
|
||||
name: "Announcment",
|
||||
element: Announcements,
|
||||
navName: "Announcment",
|
||||
},
|
||||
{
|
||||
path: "/announcement/create",
|
||||
name: "Announcment",
|
||||
element: CreateAnnouncement,
|
||||
navName: "Announcment",
|
||||
},
|
||||
//----------Point of sale orders Routes-----------------------
|
||||
|
||||
// { path: "/order/:status/:id", name: "View Order", element: ViewOdr },
|
||||
|
162
src/views/Announcment/announcement.js
Normal file
162
src/views/Announcment/announcement.js
Normal file
@ -0,0 +1,162 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TablePagination,
|
||||
Paper,
|
||||
Button,
|
||||
Typography,
|
||||
Skeleton,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { Box } from "@material-ui/core";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { isAutheticated } from "src/auth";
|
||||
|
||||
const Announcements = () => {
|
||||
const [announcements, setAnnouncements] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(5);
|
||||
const [totalAnnouncements, setTotalAnnouncements] = useState(0);
|
||||
const token = isAutheticated();
|
||||
|
||||
const fetchAnnouncements = async (page, rowsPerPage) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await axios.get("/api/announcement/get", {
|
||||
params: {
|
||||
page: page + 1, // backend uses 1-based index
|
||||
rowsPerPage,
|
||||
},
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`, // if token is necessary for authorization
|
||||
},
|
||||
});
|
||||
console.log(response);
|
||||
const { announcements, totalAnnouncements } = response.data;
|
||||
setAnnouncements(announcements);
|
||||
setTotalAnnouncements(totalAnnouncements);
|
||||
} catch (error) {
|
||||
console.error("Error fetching announcements", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchAnnouncements(page, rowsPerPage);
|
||||
}, [page, rowsPerPage]);
|
||||
|
||||
const handleChangePage = (event, newPage) => {
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (event) => {
|
||||
setRowsPerPage(parseInt(event.target.value, 10));
|
||||
setPage(0); // Reset page to 0 when changing rows per page
|
||||
};
|
||||
|
||||
const formatAMPM = (dateString) => {
|
||||
const date = new Date(dateString);
|
||||
let hours = date.getHours();
|
||||
let minutes = date.getMinutes();
|
||||
const ampm = hours >= 12 ? "PM" : "AM";
|
||||
hours = hours % 12 || 12;
|
||||
minutes = minutes < 10 ? "0" + minutes : minutes;
|
||||
return `${hours}:${minutes} ${ampm}`;
|
||||
};
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box display={"flex"} mb={2}>
|
||||
<Typography
|
||||
flex={1}
|
||||
textAlign={"center"}
|
||||
fontWeight={"bold"}
|
||||
variant="h4"
|
||||
>
|
||||
Announcements
|
||||
</Typography>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => navigate("/announcement/create")}
|
||||
sx={{ textTransform: "none" }}
|
||||
>
|
||||
Add New{" "}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead sx={{ fontWeight: "bold" }}>
|
||||
<TableRow>
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Time</TableCell>
|
||||
<TableCell>Sent to</TableCell>
|
||||
<TableCell>Message</TableCell>
|
||||
{/* <TableCell>Action</TableCell> */}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{loading ? (
|
||||
Array.from(new Array(rowsPerPage)).map((_, index) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell colSpan={5}>
|
||||
<Skeleton height={40} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
) : announcements.length > 0 ? (
|
||||
announcements.map((announcement) => (
|
||||
<TableRow key={announcement._id}>
|
||||
<TableCell>{announcement.uniqueId}</TableCell>
|
||||
<TableCell>
|
||||
{new Date(announcement.createdAt).toDateString()}
|
||||
<span>, {formatAMPM(announcement.createdAt)}</span>
|
||||
</TableCell>
|
||||
<TableCell>{announcement.sentTo.join(", ")}</TableCell>
|
||||
<TableCell>{announcement.message}</TableCell>
|
||||
{/* <TableCell>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
alert(`Viewing announcement ${announcement.id}`)
|
||||
}
|
||||
>
|
||||
View
|
||||
</Button>
|
||||
</TableCell> */}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={5} align="center">
|
||||
<Typography variant="body1">Data not found</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[5, 10, 25]}
|
||||
component="div"
|
||||
count={totalAnnouncements}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Announcements;
|
168
src/views/Announcment/createAnnouncement.js
Normal file
168
src/views/Announcment/createAnnouncement.js
Normal file
@ -0,0 +1,168 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Checkbox,
|
||||
Button,
|
||||
TextField,
|
||||
Container,
|
||||
FormControlLabel,
|
||||
Typography,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import Swal from "sweetalert2";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { isAutheticated } from "src/auth";
|
||||
// import { createAnnouncement } from './api'; // Assume this is the API call
|
||||
|
||||
const CreateAnnouncement = () => {
|
||||
const [sendTo, setSendTo] = useState({
|
||||
PDs: false,
|
||||
RDs: false,
|
||||
SCs: false,
|
||||
TMs: false,
|
||||
});
|
||||
const [message, setMessage] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
const token = isAutheticated();
|
||||
const handleCheckboxChange = (event) => {
|
||||
setSendTo({ ...sendTo, [event.target.name]: event.target.checked });
|
||||
};
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSendAnnouncement = async () => {
|
||||
if (!message || message.length > 250) {
|
||||
setError("Message is required and should not exceed 250 characters.");
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
sentTo: Object.keys(sendTo).filter((role) => sendTo[role]),
|
||||
message,
|
||||
};
|
||||
console.log("this is the send to and ", sendTo, message);
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"/api/announcement/create", // URL to your backend endpoint
|
||||
{
|
||||
sentTo: payload.sentTo, // assuming payload contains sentTo and message
|
||||
message: payload.message,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`, // if token is necessary for authorization
|
||||
},
|
||||
}
|
||||
);
|
||||
if (res.status === 201) {
|
||||
swal({
|
||||
title: "Added",
|
||||
text: "Announcement added successfully!",
|
||||
icon: "success",
|
||||
button: "ok",
|
||||
});
|
||||
navigate("/announcement");
|
||||
} else {
|
||||
swal({
|
||||
text: "Something went wrong ",
|
||||
icon: "error",
|
||||
buttons: "ok",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
swal({
|
||||
text: "Something went wrong ",
|
||||
icon: "error",
|
||||
buttons: "ok",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Typography variant="h4" mb={1}>
|
||||
New Announcement
|
||||
</Typography>
|
||||
<Box sx={{ background: "#fff", borderRadius: "1rem", padding: "1rem" }}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={sendTo.PDs}
|
||||
onChange={handleCheckboxChange}
|
||||
name="PDs"
|
||||
/>
|
||||
}
|
||||
label="PDs"
|
||||
/>
|
||||
<br />
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={sendTo.RDs}
|
||||
onChange={handleCheckboxChange}
|
||||
name="RDs"
|
||||
/>
|
||||
}
|
||||
label="RDs"
|
||||
/>
|
||||
<br />
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={sendTo.SCs}
|
||||
onChange={handleCheckboxChange}
|
||||
name="SCs"
|
||||
/>
|
||||
}
|
||||
label="SCs"
|
||||
/>
|
||||
<br />
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={sendTo.TMs}
|
||||
onChange={handleCheckboxChange}
|
||||
name="TMs"
|
||||
/>
|
||||
}
|
||||
label="TMs"
|
||||
/>
|
||||
|
||||
<br />
|
||||
<Typography fontWeight={"bold"} variant="h5">
|
||||
Messgae
|
||||
</Typography>
|
||||
<TextField
|
||||
label="Message"
|
||||
value={message}
|
||||
onChange={(e) => setMessage(e.target.value)}
|
||||
multiline
|
||||
rows={4}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
inputProps={{ maxLength: 250 }}
|
||||
helperText={`${message.length}/250`}
|
||||
/>
|
||||
{error && <Typography color="error">{error}</Typography>}
|
||||
<Box sx={{ marginTop: 2 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
sx={{ mr: "1rem" }}
|
||||
onClick={handleSendAnnouncement}
|
||||
>
|
||||
Send
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
onClick={() => navigateBack()}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateAnnouncement;
|
Loading…
Reference in New Issue
Block a user