Skip to content

Commit

Permalink
added send sms page and ui in the page
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiebones committed Mar 16, 2021
1 parent 894de7c commit 2dfccfc
Show file tree
Hide file tree
Showing 4 changed files with 351 additions and 8 deletions.
13 changes: 13 additions & 0 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import AuthorizedComponent from "./components/authorized";
import Footer from "./components/footer";
import state from "./applicationState";
import EditHostelDetails from "./components/editHostelDetails";
import SendMessageToStudent from "./components/sendMessageToStudents";
import CustomNavbar from "./components/common/customNavbar";

import GlobalStyle from "./globalStyles";
Expand Down Expand Up @@ -281,6 +282,7 @@ const App = (props) => {
currentUser={currentUser}
{...props}
/> */}

<AuthorizedComponent
path="/admin/confirm_allocation"
exact
Expand All @@ -290,6 +292,17 @@ const App = (props) => {
authorizedRole={["super-admin"]}
{...props}
/>

<AuthorizedComponent
path="/admin/send_message"
exact
component={SendMessageToStudent}
authenticated={authenticated}
currentUser={currentUser}
authorizedRole={["super-admin"]}
{...props}
/>

<AuthorizedComponent
path="/create_new_session"
exact
Expand Down
19 changes: 11 additions & 8 deletions client/src/components/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ const Navbar = ({ authenticated, currentUser }) => {

let history = useHistory();

useEffect(() => {

}, [isAuth])

useEffect(() => {}, [isAuth]);

const handleLogOut = (e) => {
e.preventDefault();
Expand All @@ -82,10 +79,8 @@ const Navbar = ({ authenticated, currentUser }) => {
store.clearAll();
client.clearStore();
history.replace("/");

};


return (
<NavbarStyles>
<div className="header-nav">
Expand Down Expand Up @@ -180,8 +175,6 @@ const Navbar = ({ authenticated, currentUser }) => {
Edit Hostel Details
</StyledLink>



<StyledLink
exact
to="/view_students_in_rooms"
Expand Down Expand Up @@ -268,6 +261,16 @@ const Navbar = ({ authenticated, currentUser }) => {
</StyledLink>
</div>
</li>

<li className="nav-item">
<StyledLink
className="nav-link"
exact
to="/admin/send_message"
>
Send SMS
</StyledLink>
</li>
</React.Fragment>
)}

Expand Down
303 changes: 303 additions & 0 deletions client/src/components/sendMessageToStudents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
import React, { useEffect, useState } from "react";
import {
GetAllHallsWithRoomDetails,
GetSMSCreditAvailable,
} from "../graphql/queries";
import { useLazyQuery, useQuery } from "@apollo/client";
import styled from "styled-components";
import Loading from "./common/loading";

const SendMessageToStudentStyles = styled.div`
.div-hostel-select {
max-height: 900px;
overflow-y: scroll;
}
.word-length {
float: right;
font-size: 17px;
}
.sms-text {
height: 250px;
}
.room-total {
float: right;
}
.room-div {
width: 100px;
height: 50px;
text-align: center;
margin: 10px;
padding-top: 5px;
background-color: green;
color: #fff;
display: inline-block;
position: relative;
cursor: pointer;
.bedTotal {
float: right;
position: absolute;
bottom: 0;
right: 5px;
}
.selected {
color: gray;
}
}
`;

const filterForDuplicate = (oldArray, newValue, key) => {
const returnRemain = oldArray.filter((value) => value[key] != newValue[key]);
return [...returnRemain, newValue];
};

const _groupByHostel = (arrayOfHostel = []) => {
let hostelGroup = arrayOfHostel.reduce((r, a) => {
r[a.hostel] = r[a.hostel] || [];
r[a.hostel].push(a);
return r;
}, Object.create(null));
return hostelGroup;
};

const SendMessageToStudent = () => {
const [hostels, setHostels] = useState(null);
const [selectedHostel, setSelectedHostel] = useState(null);
const [messageArray, setMessageArray] = useState([]);
const { loading, data, error } = useQuery(GetAllHallsWithRoomDetails);
const [getCredit, getCreditResult] = useLazyQuery(GetSMSCreditAvailable);
const [errors, setErrors] = useState(null);
const [smsCredits, setSmsCredit] = useState(null);
const [creditQueryLoading, setQueryLoading] = useState(false);
const [groupObject, setGroupObject] = useState(null);
const [totalWords, setTotalWords] = useState(0);
const [sms, setSMS] = useState("");
const [smsPage, setSMSPage] = useState(1);

let total = 0;

useEffect(() => {
const result = _groupByHostel(messageArray);
setGroupObject(result);
}, [messageArray]);

useEffect(() => {
if (error) {
setErrors(error);
}
if (data) {
const hostelData = data.getAllHalls;
setHostels(hostelData);
}
}, [data, error]);

useEffect(() => {
//setQueryLoading(true);
//getCredit();
}, []);

useEffect(() => {
if (getCreditResult.error) {
setQueryLoading(false);
setErrors(getCreditResult.error);
}
if (getCreditResult.data) {
const credits = getCreditResult.data.checkCredit;
setQueryLoading(false);
setSmsCredit(credits);
}
}, [getCreditResult.data, getCreditResult.error]);

const selectedHostelChange = (e) => {
const value = e.target.value;
if (value == "0") return;
if (value === "all_students") {
//the message is for all the students in the hostel
//loop through the hostels and get the total number of msg to send
let hostelArray = [];
hostels.map((hostel) => {
let roomsArray = hostel.rooms;
roomsArray.map((room) => {
let hostelObject = {};
hostelObject.hostel = hostel.hallName;
hostelObject.totalBedSpace = room.totalBedSpace;
hostelObject.roomNumber = room.roomNumber;
hostelObject.id = room.id;
hostelArray.push(hostelObject);
});
});

setMessageArray(hostelArray);
} else {
//get the particular selected hostel
const selectedHostel = hostels.find((hostel) => hostel.id === value);
setSelectedHostel(selectedHostel);
}
};

const handleRoomSelectionChange = ({ allRooms, ...rest }) => {
if (!allRooms) {
const { roomNumber, totalBedSpace, id } = rest;
const obj = {
roomNumber,
totalBedSpace,
id,
hostel: selectedHostel.hallName,
};
setMessageArray((prev) => filterForDuplicate(prev, obj, "id"));
}
if (allRooms) {
//we are selecting all the rooms of the selected hostel

selectedHostel.rooms.map((room) => {
const { roomNumber, totalBedSpace, id } = room;
const obj = {
roomNumber,
totalBedSpace,
id,
hostel: selectedHostel.hallName,
};
setMessageArray((prev) => filterForDuplicate(prev, obj, "id"));
});
}
};

const handleTextChange = (e) => {
const value = e.target.value;
const textLength = 9 + value.length;
setSMS(value);
setTotalWords(textLength);
setSMSPage(Math.ceil(textLength / 160));
};

return (
<SendMessageToStudentStyles>
<div className="row">
<div className="col-md-6">
<div className="text-center">
<h3 className="text-info">Send SMS To Students</h3>
{errors && <p className="text-danger lead">{errors.message}</p>}
</div>
<select
className="form-control form-select form-select-lg mb-3"
onChange={selectedHostelChange}
>
<option value="0">select hostel</option>
{loading && <option>loading.....</option>}
<option value="all_students">
send message to everyone residing in the hostel
</option>
{hostels &&
hostels.map(({ id, hallName }) => {
return (
<option key={id} value={id}>
{hallName.toUpperCase()}
</option>
);
})}
</select>

{selectedHostel &&
selectedHostel.rooms.map(({ roomNumber, totalBedSpace, id }) => {
return (
<div
className="room-div"
key={id}
onClick={() =>
handleRoomSelectionChange({
roomNumber,
totalBedSpace,
id,
allRooms: false,
})
}
>
<p>
<span>{roomNumber}</span>{" "}
<span className="bedTotal">{totalBedSpace}</span>
</p>
</div>
);
})}

{selectedHostel && (
<div
className="room-div"
onClick={() => handleRoomSelectionChange({ allRooms: true })}
>
<p>
Select All
<span className="bedTotal"></span>
</p>
</div>
)}

<div className="form-floating mt-4 mb-2">
<textarea
className="form-control sms-text"
placeholder="type sms here"
id="floatingTextarea2"
onChange={handleTextChange}
></textarea>

<label>
<span>{smsPage} page(s)</span>
</label>

<label htmlFor="floatingTextarea2" className="word-length">
<span className="word-length">{totalWords}</span>
</label>
</div>
</div>

<div className="col-md-4 offset-md-1">
<div className="div-hostel-select">
{creditQueryLoading && (
<div className="text-center">
<Loading />
</div>
)}
{smsCredits && (
<p className="lead">
Available Credits: {smsCredits.sms_credits}
</p>
)}

{groupObject &&
Object.keys(groupObject).map((k) => {
return (
<div className="hostel" key={k}>
<p className="text-center lead">{k.toUpperCase()}</p>
{groupObject[k].map(({ roomNumber, totalBedSpace, id }) => {
total += +totalBedSpace;
return (
<div className="room" key={id}>
<p>
<span>{roomNumber}</span>
<span className="room-total">{totalBedSpace}</span>
</p>
</div>
);
})}
</div>
);
})}

{total > 0 && (
<div className="text-center">
<p className="lead text-primary">Total messages: {total}</p>
<button className="btn btn-danger">
Send SMS to {total} people
</button>
</div>
)}
</div>
</div>
</div>

</SendMessageToStudentStyles>
);
};

export default SendMessageToStudent;
Loading

0 comments on commit 2dfccfc

Please sign in to comment.