Decorate all existing pages
This commit is contained in:
parent
334bd5542b
commit
e70fb22ac3
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.2fa2d232.css",
|
"main.css": "/static/css/main.2fa2d232.css",
|
||||||
"main.js": "/static/js/main.77186374.js",
|
"main.js": "/static/js/main.da419ea1.js",
|
||||||
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
||||||
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.2fa2d232.css.map": "/static/css/main.2fa2d232.css.map",
|
"main.2fa2d232.css.map": "/static/css/main.2fa2d232.css.map",
|
||||||
"main.77186374.js.map": "/static/js/main.77186374.js.map",
|
"main.da419ea1.js.map": "/static/js/main.da419ea1.js.map",
|
||||||
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.2fa2d232.css",
|
"static/css/main.2fa2d232.css",
|
||||||
"static/js/main.77186374.js"
|
"static/js/main.da419ea1.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.77186374.js"></script><link href="/static/css/main.2fa2d232.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.da419ea1.js"></script><link href="/static/css/main.2fa2d232.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||||
@ -96,9 +96,11 @@ const CustomerReport = () => {
|
|||||||
const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
|
const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
|
||||||
TransRoutesService.getAll(dateText).then(data => {
|
TransRoutesService.getAll(dateText).then(data => {
|
||||||
setRoutes(data.data);
|
setRoutes(data.data);
|
||||||
|
setShowDateDropdown(false)
|
||||||
})
|
})
|
||||||
ReportService.getReportsByDateAndType(dateText, REPORT_TYPE.ADMIN_CUSTOMER_REPORT).then(data => {
|
ReportService.getReportsByDateAndType(dateText, REPORT_TYPE.ADMIN_CUSTOMER_REPORT).then(data => {
|
||||||
setExistedReports(data.data);
|
setExistedReports(data.data);
|
||||||
|
setShowDateDropdown(false);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,7 +750,7 @@ const CustomerReport = () => {
|
|||||||
className="me-2"
|
className="me-2"
|
||||||
show={showDateDropdown}
|
show={showDateDropdown}
|
||||||
onToggle={() => setShowDateDropdown(!showDateDropdown)}
|
onToggle={() => setShowDateDropdown(!showDateDropdown)}
|
||||||
autoClose="outside"
|
autoClose={false}
|
||||||
>
|
>
|
||||||
<Dropdown.Toggle variant="primary">
|
<Dropdown.Toggle variant="primary">
|
||||||
<CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
|
<CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
|
||||||
@ -761,7 +763,7 @@ const CustomerReport = () => {
|
|||||||
className="me-2"
|
className="me-2"
|
||||||
show={showFilterReportDropdown}
|
show={showFilterReportDropdown}
|
||||||
onToggle={() => setShowFilterReportDropdown(!showFilterReportDropdown)}
|
onToggle={() => setShowFilterReportDropdown(!showFilterReportDropdown)}
|
||||||
autoClose="outside"
|
autoClose={false}
|
||||||
>
|
>
|
||||||
<Dropdown.Toggle variant="primary">
|
<Dropdown.Toggle variant="primary">
|
||||||
<Filter size={16} className="me-2"></Filter>Filter
|
<Filter size={16} className="me-2"></Filter>Filter
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import React, {useState, useEffect} from "react";
|
|||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, CenterPhoneService } from "../../services";
|
import { AuthService, CenterPhoneService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
import { Columns, Download, Send, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
|
||||||
|
|
||||||
const CenterPhoneList = () => {
|
const CenterPhoneList = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -30,45 +32,71 @@ const CenterPhoneList = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const redirectTo = () => {
|
||||||
|
navigate(`/messages/list`)
|
||||||
|
}
|
||||||
|
|
||||||
const goToEdit = (id) => {
|
const goToEdit = (id) => {
|
||||||
navigate(`/center-phones/edit/${id}`)
|
navigate(`/center-phones/edit/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const goToCreateNew = () => {
|
||||||
|
navigate(`/center-phones`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Center Phone
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>All Phones <button className="btn btn-link btn-sm" onClick={() => {redirectToAdmin()}}>Back</button></h5>
|
<h4>
|
||||||
|
All Phones <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
|
||||||
<div className="col-md-12">
|
<div className="app-main-content-list-container">
|
||||||
<div className="mb-4">Keyword: <input type="text" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)}/></div>
|
<div className="app-main-content-list-func-container">
|
||||||
<table className="personnel-info-table">
|
<Tabs defaultActiveKey="allMessages" id="messages-tab">
|
||||||
<thead>
|
<Tab eventKey="allMessages" title="All Messages">
|
||||||
<tr>
|
<table className="personnel-info-table">
|
||||||
<th>Phone Title</th>
|
<thead>
|
||||||
<th>Phone Number</th>
|
<tr>
|
||||||
<th>Activated</th>
|
<th className="th-index">No.</th>
|
||||||
<th></th>
|
<th>Phone Title</th>
|
||||||
</tr>
|
<th>Phone Number</th>
|
||||||
|
<th>Activated</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
|
||||||
{
|
</thead>
|
||||||
phones && phones.filter((item)=> item?.phone_number.includes(keyword) || item?.phone_title.toLowerCase().includes(keyword.toLowerCase())).map(phone => <tr key={phone.id}>
|
<tbody>
|
||||||
<td>{phone?.phone_title}</td>
|
{
|
||||||
<td>{phone?.phone_number}</td>
|
phones && phones.filter((item)=> item?.phone_number.includes(keyword) || item?.phone_title.toLowerCase().includes(keyword.toLowerCase())).map((phone, index )=> <tr key={phone.id}>
|
||||||
<td>{phone?.activated ? 'Yes': 'No'}</td>
|
<td className="td-index">{index + 1}</td>
|
||||||
<td>
|
<td> <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(phone?.id)}></PencilSquare> { phone?.phone_title }</td>
|
||||||
<button className="btn btn-primary btn-sm me-2" onClick={() => goToEdit(phone?.id)}>Edit</button>
|
<td>{phone?.phone_number}</td>
|
||||||
</td>
|
<td>{phone?.activated ? 'Yes': 'No'}</td>
|
||||||
</tr>)
|
<td>
|
||||||
}
|
<button className="btn btn-primary btn-sm" onClick={() => goToEdit(phone?.id)}>Edit</button>
|
||||||
</tbody>
|
</td>
|
||||||
</table>
|
</tr>)
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
<div className="list-func-panel">
|
||||||
|
<input className="me-2 with-search-icon" type="text" placeholder="Search" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)} />
|
||||||
|
{/* <button className="btn btn-primary me-2"><Columns size={16} className="me-2"></Columns>Manage Table</button> */}
|
||||||
|
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Phone</button>
|
||||||
|
{/* <button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button> */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, CenterPhoneService } from "../../services";
|
import { AuthService, CenterPhoneService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
|
||||||
const CreateCenterPhone = () => {
|
const CreateCenterPhone = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -18,11 +19,12 @@ const CreateCenterPhone = () => {
|
|||||||
|
|
||||||
|
|
||||||
const redirectTo = () => {
|
const redirectTo = () => {
|
||||||
if (params.get('from') === 'medical') {
|
// if (params.get('from') === 'medical') {
|
||||||
navigate(`/medical/`);
|
// navigate(`/medical/`);
|
||||||
} else {
|
// } else {
|
||||||
navigate(`/admin/customer-report`)
|
// navigate(`/admin/customer-report`)
|
||||||
}
|
//}
|
||||||
|
navigate(`/center-phones/list`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ const CreateCenterPhone = () => {
|
|||||||
phone_number: phoneNumber
|
phone_number: phoneNumber
|
||||||
};
|
};
|
||||||
CenterPhoneService.createNewCenterPhone(data).then(() => {
|
CenterPhoneService.createNewCenterPhone(data).then(() => {
|
||||||
navigate(`/center-phones/list`)
|
navigate(`/center-phones/list`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,22 +42,44 @@ const CreateCenterPhone = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Center Phone
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>Create New Center Phone Item <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<h4>
|
||||||
|
Create Center Phone <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
|
||||||
<div className="col-md-4 mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div>Phone Title(*):</div> <input type="text" value={phoneTitle || ''} onChange={e => setPhoneTitle(e.target.value)}/>
|
<div className="app-main-content-list-func-container">
|
||||||
</div>
|
<Tabs defaultActiveKey="phoneCreation" id="phone-creation-tab">
|
||||||
<div className="col-md-4 mb-4">
|
<Tab eventKey="phoneCreation" title="Create Center Phone">
|
||||||
<div>Phone Number(*):</div> <input type="text" value={phoneNumber || ''} onChange={e => setPhoneNumber(e.target.value)}/>
|
<div className="app-main-content-fields-section">
|
||||||
</div>
|
<div className="me-4">
|
||||||
</div>
|
<div className="field-label">Phone Title
|
||||||
<div className="list row mb-5">
|
<span className="required">*</span>
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12">
|
</div>
|
||||||
<button className="btn btn-primary btn-sm" onClick={() => savePhone()}> Save </button>
|
<input type="text" value={phoneTitle || ''} onChange={e => setPhoneTitle(e.target.value)}/>
|
||||||
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Phone Number
|
||||||
|
<span className="required">*</span>
|
||||||
|
</div>
|
||||||
|
<input type="text" value={phoneNumber || ''} onChange={e => setPhoneNumber(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => savePhone()}> Save </button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { AuthService, CenterPhoneService } from "../../services";
|
import { AuthService, CenterPhoneService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
|
||||||
const UpdateCenterPhone = () => {
|
const UpdateCenterPhone = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -46,25 +47,49 @@ const UpdateCenterPhone = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Center Phone
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>Update Phone <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<h4>
|
||||||
|
Update Center Phone <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
|
||||||
<div className="col-md-4 mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div>Phone Title(*):</div> <input type="text" value={phoneTitle || ''} onChange={e => setPhoneTitle(e.target.value)}/>
|
<div className="app-main-content-list-func-container">
|
||||||
</div>
|
<Tabs defaultActiveKey="updatePhone" id="update-phone-tab">
|
||||||
<div className="col-md-4 mb-4">
|
<Tab eventKey="updatePhone" title="Update Center Phone">
|
||||||
<div>Phone Number(*):</div> <input type="text" value={phoneNumber || ''} onChange={e => setPhoneNumber(e.target.value)}/>
|
<div className="app-main-content-fields-section">
|
||||||
</div>
|
<div className="me-4">
|
||||||
<div className="col-md-4 mb-4">
|
<div className="field-label">Phone Title
|
||||||
<div>Activated:</div> <input type="checkbox" value={activated} checked={activated === true} onChange={e => setActivated(!activated)}/>
|
<span className="required">*</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<input type="text" value={phoneTitle || ''} onChange={e => setPhoneTitle(e.target.value)}/>
|
||||||
<div className="list row mb-5">
|
</div>
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12">
|
<div className="me-4">
|
||||||
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => savePhone()}> Save </button>
|
<div className="field-label">Phone Number
|
||||||
<button className="btn btn-default btn-sm mb-2" onClick={() => redirectTo()}> Cancel </button>
|
<span className="required">*</span>
|
||||||
|
</div>
|
||||||
|
<input type="text" value={phoneNumber || ''} onChange={e => setPhoneNumber(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Activated
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" value={activated} checked={activated === true} onChange={e => setActivated(!activated)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => savePhone()}> Save </button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -283,7 +283,42 @@ const CreateCustomer = () => {
|
|||||||
<input type="email" placeholder="e.g.,example@gmail.com" className="long" value={email || ''} onChange={e => setEmail(e.target.value)}/>
|
<input type="email" placeholder="e.g.,example@gmail.com" className="long" value={email || ''} onChange={e => setEmail(e.target.value)}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* We will do Address and Emergency later */}
|
{/* We will do Address and Emergency later */}
|
||||||
|
<h6 className="text-primary">Home Addresses</h6>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 1 <span className="required">*</span></div>
|
||||||
|
<input type="text" value={address1 || ''} onChange={e => setAddress1(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 2</div>
|
||||||
|
<input type="text" value={address2 || ''} onChange={e => setAddress2(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 3</div>
|
||||||
|
<input type="text" value={address3 || ''} onChange={e => setAddress3(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 4</div>
|
||||||
|
<input type="text" value={address4 || ''} onChange={e => setAddress4(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 5</div>
|
||||||
|
<input type="text" value={address5 || ''} onChange={e => setAddress5(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6 className="text-primary">Emergency Contact Information</h6>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Emergency Contact <span className="required">*</span> </div>
|
||||||
|
<input type="text" placeholder="e.g.,John 240-463-1698" className="long" value={emergencyContact || ''} onChange={e => setEmergencyContact(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h6 className="text-primary">Service Information</h6>
|
<h6 className="text-primary">Service Information</h6>
|
||||||
<div className="app-main-content-fields-section">
|
<div className="app-main-content-fields-section">
|
||||||
<div className="me-4">
|
<div className="me-4">
|
||||||
|
|||||||
@ -465,6 +465,40 @@ const UpdateCustomer = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* We will do Address and Emergency later */}
|
{/* We will do Address and Emergency later */}
|
||||||
|
{/* We will do Address and Emergency later */}
|
||||||
|
<h6 className="text-primary">Home Addresses</h6>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 1 <span className="required">*</span></div>
|
||||||
|
<input type="text" value={address1 || ''} onChange={e => setAddress1(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 2</div>
|
||||||
|
<input type="text" value={address2 || ''} onChange={e => setAddress2(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 3</div>
|
||||||
|
<input type="text" value={address3 || ''} onChange={e => setAddress3(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 4</div>
|
||||||
|
<input type="text" value={address4 || ''} onChange={e => setAddress4(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Address 5</div>
|
||||||
|
<input type="text" value={address5 || ''} onChange={e => setAddress5(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6 className="text-primary">Emergency Contact Information</h6>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Emergency Contact <span className="required">*</span> </div>
|
||||||
|
<input type="text" placeholder="e.g.,John 240-463-1698" className="long" value={emergencyContact || ''} onChange={e => setEmergencyContact(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<h6 className="text-primary">Service Information</h6>
|
<h6 className="text-primary">Service Information</h6>
|
||||||
<div className="app-main-content-fields-section">
|
<div className="app-main-content-fields-section">
|
||||||
<div className="me-4">
|
<div className="me-4">
|
||||||
|
|||||||
@ -1,77 +1,109 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, MessageService } from "../../services";
|
import { AuthService, MessageService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
|
||||||
const CreateMessage = () => {
|
const CreateMessage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!AuthService.canAddOrEditRoutes() && !AuthService.canViewRoutes() && !AuthService.canAccessLegacySystem()) {
|
if (!AuthService.canAddOrEditRoutes() && !AuthService.canViewRoutes() && !AuthService.canAccessLegacySystem()) {
|
||||||
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change a dispatcher or admin account to login.')
|
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change a dispatcher or admin account to login.')
|
||||||
AuthService.logout();
|
AuthService.logout();
|
||||||
navigate(`/login`);
|
navigate(`/login`);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
const [messageGroup, setMessageGroup] = useState();
|
const [messageGroup, setMessageGroup] = useState();
|
||||||
const [messageName, setMessageName] = useState('');
|
const [messageName, setMessageName] = useState('');
|
||||||
const [messageTitle, setMessageTitle] = useState('');
|
const [messageTitle, setMessageTitle] = useState('');
|
||||||
const [messageBody, setMessageBody] = useState('');
|
const [messageBody, setMessageBody] = useState('');
|
||||||
const [language, setLanguage] = useState('');
|
const [language, setLanguage] = useState('');
|
||||||
|
|
||||||
const redirectTo = () => {
|
const redirectTo = () => {
|
||||||
navigate(`/messages/list`);
|
navigate(`/messages/list`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveMessage = () => {
|
const saveMessage = () => {
|
||||||
const data = {
|
const data = {
|
||||||
message_group: messageGroup,
|
message_group: messageGroup,
|
||||||
message_title: messageTitle,
|
message_title: messageTitle,
|
||||||
message_body: messageBody,
|
message_body: messageBody,
|
||||||
message_name: messageName,
|
message_name: messageName,
|
||||||
language: language
|
language: language
|
||||||
};
|
};
|
||||||
MessageService.createMessage(data).then(() => redirectTo())
|
MessageService.createMessage(data).then(() => redirectTo())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>Create New Message Template <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<h4>
|
||||||
|
Create Message Template <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div className="col-md-4 mb-4">
|
<div className="app-main-content-list-func-container">
|
||||||
<div>Message Group (*):</div>
|
<Tabs defaultActiveKey="messageCreation" id="message-template-tab">
|
||||||
<select value={messageGroup} onChange={e => setMessageGroup(e.target.value)} required>
|
<Tab eventKey="messageCreation" title="Create Message Template">
|
||||||
<option value=""></option>
|
<div className="app-main-content-fields-section">
|
||||||
<option value={1}>1</option>
|
<div className="me-4">
|
||||||
<option value={2}>2</option>
|
<div className="field-label">Message Group
|
||||||
<option value={3}>3</option>
|
<span className="required">*</span>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
<select value={messageGroup} onChange={e => setMessageGroup(e.target.value)} required>
|
||||||
<div className="col-md-4 mb-4">
|
<option value=""></option>
|
||||||
<div>Message Name:</div> <input type="text" value={messageName || ''} onChange={e => setMessageName(e.target.value)}/>
|
<option value={1}>1</option>
|
||||||
</div>
|
<option value={2}>2</option>
|
||||||
<div className="col-md-4 mb-4">
|
<option value={3}>3</option>
|
||||||
<div>Language:</div>
|
</select>
|
||||||
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
</div>
|
||||||
<option value=""></option>
|
<div className="me-4">
|
||||||
<option value="English">English</option>
|
<div className="field-label">Message Name
|
||||||
<option value="Chinese">Chinese</option>
|
<span className="required">*</span>
|
||||||
<option value="Vietnamese">Vietnamese</option>
|
</div>
|
||||||
<option value="Korean">Korean</option>
|
<input type="text" value={messageName || ''} onChange={e => setMessageName(e.target.value)}/>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 mb-4">
|
<div className="app-main-content-fields-section">
|
||||||
<div>Message Title:</div> <input type="text" value={messageTitle || ''} onChange={e => setMessageTitle(e.target.value)}/>
|
<div className="me-4">
|
||||||
</div>
|
<div className="field-label">Language
|
||||||
<div className="col-md-12 mb-4">
|
</div>
|
||||||
<div>Message Body:</div> <textarea value={messageBody || ''} onChange={e => setMessageBody(e.target.value)}/>
|
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
||||||
</div>
|
<option value=""></option>
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12">
|
<option value="English">English</option>
|
||||||
<button className="btn btn-primary btn-sm" onClick={() => saveMessage()}> Save </button>
|
<option value="Chinese">Chinese</option>
|
||||||
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
|
<option value="Vietnamese">Vietnamese</option>
|
||||||
|
<option value="Korean">Korean</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Message Title
|
||||||
|
</div>
|
||||||
|
<input type="text" value={messageTitle || ''} onChange={e => setMessageTitle(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Message Body
|
||||||
|
</div>
|
||||||
|
<textarea value={messageBody || ''} onChange={e => setMessageBody(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => saveMessage()}> Save </button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import React, {useState, useEffect} from "react";
|
import React, {useState, useEffect} from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, MessageService } from "../../services";
|
import { AuthService, MessageService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
import { Columns, Download, Send, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
|
||||||
|
|
||||||
const MessageList = () => {
|
const MessageList = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -30,6 +32,10 @@ const MessageList = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const goToSendMessage = () => {
|
||||||
|
navigate(`/messages/send-message`);
|
||||||
|
}
|
||||||
|
|
||||||
const goToEdit = (id) => {
|
const goToEdit = (id) => {
|
||||||
navigate(`/messages/edit/${id}`)
|
navigate(`/messages/edit/${id}`)
|
||||||
}
|
}
|
||||||
@ -42,42 +48,53 @@ const MessageList = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>All Messages <button className="btn btn-link btn-sm" onClick={() => {redirectToAdmin()}}>Back</button>
|
<h4>All Messages Templates
|
||||||
<button className="btn btn-link btn-sm" onClick={() => {goToCreate()}}>Go To Create Message Template</button>
|
</h4>
|
||||||
</h5>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div className="col-md-12">
|
<div className="app-main-content-list-func-container">
|
||||||
<table className="personnel-info-table">
|
<Tabs defaultActiveKey="allMessages" id="messages-tab">
|
||||||
<thead>
|
<Tab eventKey="allMessages" title="All Messages">
|
||||||
<tr>
|
<table className="personnel-info-table">
|
||||||
<th>Message Group</th>
|
<thead>
|
||||||
<th>Message Name</th>
|
<tr>
|
||||||
<th>Language</th>
|
<th className="th-index">No.</th>
|
||||||
<th>Message Title</th>
|
<th>Message Group</th>
|
||||||
<th>Message Body</th>
|
<th>Message Name</th>
|
||||||
<th></th>
|
<th>Language</th>
|
||||||
</tr>
|
<th>Message Title</th>
|
||||||
|
<th>Message Body</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
|
||||||
{
|
</thead>
|
||||||
messages && messages.map(message => <tr key={message.id}>
|
<tbody>
|
||||||
<td>{message?.message_group}</td>
|
{
|
||||||
<td>{message?.message_name}</td>
|
messages && messages.map((message, index) => <tr key={message.id}>
|
||||||
<td>{message?.language}</td>
|
<td className="td-index">{index + 1}</td>
|
||||||
<td>{message?.message_title}</td>
|
<td>{message?.message_group}</td>
|
||||||
<td>{message?.message_body}</td>
|
<td><PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(message?.id)}></PencilSquare> {message?.message_name}</td>
|
||||||
<td>
|
<td>{message?.language}</td>
|
||||||
<button className="btn btn-primary btn-sm me-2" onClick={() => goToEdit(message?.id)}>Edit</button>
|
<td>{message?.message_title}</td>
|
||||||
</td>
|
<td>{message?.message_body}</td>
|
||||||
</tr>)
|
</tr>)
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
<div className="list-func-panel">
|
||||||
|
<button className="btn btn-primary me-2" onClick={() => goToCreate()}><Plus size={16}></Plus>Create New Message</button>
|
||||||
|
<button className="btn btn-primary me-2" onClick={() => goToSendMessage()}><Send size={16} className="me-2"></Send> Send Message</button>
|
||||||
|
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { AuthService, MessageService } from "../../services";
|
import { AuthService, MessageService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
|
||||||
|
|
||||||
const MessageTokenEditor = () => {
|
const MessageTokenEditor = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -32,7 +34,7 @@ const MessageTokenEditor = () => {
|
|||||||
}, [currentMessageToken])
|
}, [currentMessageToken])
|
||||||
|
|
||||||
const redirectTo = () => {
|
const redirectTo = () => {
|
||||||
navigate(`/admin`);
|
navigate(`/messages/list`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveMessageToken = () => {
|
const saveMessageToken = () => {
|
||||||
@ -55,19 +57,38 @@ const MessageTokenEditor = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>Update Message Token <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<h4>
|
||||||
|
Update Message Token <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
|
||||||
<div className="col-md-12 mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div>Message Token:</div> <input type="text" value={messageToken || ''} onChange={e => setMessageToken(e.target.value)}/>
|
<div className="app-main-content-list-func-container">
|
||||||
</div>
|
<Tabs defaultActiveKey="messageCreation" id="message-template-tab">
|
||||||
</div>
|
<Tab eventKey="messageCreation" title="Update Message Template">
|
||||||
<div className="list row mb-5">
|
<div className="app-main-content-fields-section">
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12">
|
<div className="me-4">
|
||||||
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveMessageToken()}> Save </button>
|
<div className="field-label">Message Token
|
||||||
<button className="btn btn-default btn-sm mb-2" onClick={() => redirectTo()}> Cancel </button>
|
<span className="required">*</span>
|
||||||
|
</div>
|
||||||
|
<input type="text" value={messageToken || ''} onChange={e => setMessageToken(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => saveMessageToken()}> Save </button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import React, {useEffect, useState} from "react";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, MessageService, CustomerService } from "../../services";
|
import { AuthService, MessageService, CustomerService } from "../../services";
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
import { SendCheck } from "react-bootstrap-icons";
|
||||||
|
|
||||||
const SendMessage = () => {
|
const SendMessage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -35,6 +37,14 @@ const SendMessage = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const redirectToList = () => {
|
||||||
|
navigate(`/messages/list`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const goToSentMessages = () => {
|
||||||
|
navigate(`/messages/sent-messages/list`);
|
||||||
|
}
|
||||||
|
|
||||||
const sendMessage = () => {
|
const sendMessage = () => {
|
||||||
setShowSuccessInfo(false);
|
setShowSuccessInfo(false);
|
||||||
const data = {
|
const data = {
|
||||||
@ -56,40 +66,127 @@ const SendMessage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
<div className="col-md-12 text-primary">
|
<Breadcrumb>
|
||||||
<h5>Send Message <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Send Message
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="col-md-12 text-primary">
|
||||||
|
<h4>Send Message <button className="btn btn-link btn-sm" onClick={() => {redirectToList()}}>Back</button></h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div className="col-md-12 mb-4">
|
<div className="app-main-content-list-func-container">
|
||||||
<div>Type in Phone Number:</div> <input type="text" value={contactPhone || ''} onChange={e => setContactPhone(e.target.value)}/>
|
<Tabs defaultActiveKey="sendMessage" id="send-message-tab">
|
||||||
|
<Tab eventKey="sendMessage" title="Send Message">
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Type in Phone Number
|
||||||
|
<span className="required">*</span>
|
||||||
|
</div>
|
||||||
|
<input type="text" value={contactPhone || ''} onChange={e => setContactPhone(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">OR</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Select From Participant Mobile Number List
|
||||||
|
<span className="required">*</span>
|
||||||
|
</div>
|
||||||
|
<Select styles={{
|
||||||
|
control: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
width: '350px',
|
||||||
|
height: '45px',
|
||||||
|
'padding-top': 0,
|
||||||
|
'padding-bottom': 0,
|
||||||
|
'margin-top': 0,
|
||||||
|
'margin-bottom': 0
|
||||||
|
}),
|
||||||
|
indicatorSeparator: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
width: 0
|
||||||
|
}),
|
||||||
|
indicatorsContainer: (baseStyles) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px'
|
||||||
|
}),
|
||||||
|
placeholder: (baseStyles) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px',
|
||||||
|
'font-size': '13px'
|
||||||
|
}),
|
||||||
|
singleValue: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px',
|
||||||
|
'font-size': '13px'
|
||||||
|
})
|
||||||
|
}} value={contactSeniorPhone || ''} onChange={selectedData => onContactSeniorChange(selectedData)} options={[{value: '', label: ''}, ...seniorPhoneList.map(senior => ({
|
||||||
|
value: senior?.mobile_phone || '',
|
||||||
|
label: `${senior?.name}(${senior?.name_cn}) - ${senior?.mobile_phone}` || '',
|
||||||
|
}))]}></Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Select Message Template (Optional)</div>
|
||||||
|
<Select styles={{
|
||||||
|
control: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
width: '350px',
|
||||||
|
height: '45px',
|
||||||
|
'padding-top': 0,
|
||||||
|
'padding-bottom': 0,
|
||||||
|
'margin-top': 0,
|
||||||
|
'margin-bottom': 0
|
||||||
|
}),
|
||||||
|
indicatorSeparator: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
width: 0
|
||||||
|
}),
|
||||||
|
indicatorsContainer: (baseStyles) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px'
|
||||||
|
}),
|
||||||
|
placeholder: (baseStyles) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px',
|
||||||
|
'font-size': '13px'
|
||||||
|
}),
|
||||||
|
singleValue: (baseStyles, state) => ({
|
||||||
|
...baseStyles,
|
||||||
|
'margin-top': '-10px',
|
||||||
|
'font-size': '13px'
|
||||||
|
})
|
||||||
|
}} value={messageTemplate || ''} onChange={selectedData => {setMessageTemplate(selectedData); setMessageText(selectedData.value)}} options={[{value: '', label: ''}, ...messageTempateList.map(template => ({
|
||||||
|
value: template.message_body || '',
|
||||||
|
label: template.message_body || '',
|
||||||
|
}))]}></Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Message Content</div>
|
||||||
|
<textarea value={messageText || ''} onChange={e => setMessageText(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="list row mb-5">
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => sendMessage()}> Save </button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{showSuccessInfo && <div className="col-md-12 mb-4 alert alert-success" role="alert">
|
||||||
|
Message Sent!
|
||||||
|
</div>}
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
<div className="list-func-panel">
|
||||||
|
<button className="btn btn-primary btn-sm" onClick={() => goToSentMessages()}><SendCheck size={16} className="me-2"></SendCheck>View All Sent Messages</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 mb-4">OR</div>
|
|
||||||
<div className="col-md-6 col-sm-12 col-xs-12 mb-4">
|
|
||||||
<div>Select From Participant Mobile Number List:</div>
|
|
||||||
<Select value={contactSeniorPhone || ''} onChange={selectedData => onContactSeniorChange(selectedData)} options={[{value: '', label: ''}, ...seniorPhoneList.map(senior => ({
|
|
||||||
value: senior?.mobile_phone || '',
|
|
||||||
label: `${senior?.name}(${senior?.name_cn}) - ${senior?.mobile_phone}` || '',
|
|
||||||
}))]}></Select>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-12 col-sm-12 col-xs-12 mb-4">
|
|
||||||
<div>Select Message Template (Not Required):</div>
|
|
||||||
<Select value={messageTemplate || ''} onChange={selectedData => {setMessageTemplate(selectedData); setMessageText(selectedData.value)}} options={[{value: '', label: ''}, ...messageTempateList.map(template => ({
|
|
||||||
value: template.message_body || '',
|
|
||||||
label: template.message_body || '',
|
|
||||||
}))]}></Select>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-12 mb-4">
|
|
||||||
<div>Message Text:</div> <textarea value={messageText || ''} onChange={e => setMessageText(e.target.value)}/>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12 mb-4">
|
|
||||||
<button className="btn btn-primary btn-sm" onClick={() => sendMessage()}> Send Message </button>
|
|
||||||
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{showSuccessInfo && <div className="col-md-12 mb-4 alert alert-success" role="alert">
|
|
||||||
Message Sent!
|
|
||||||
</div>}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,11 +2,14 @@ import React, {useState, useEffect} from "react";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { AuthService, MessageService } from "../../services";
|
import { AuthService, MessageService } from "../../services";
|
||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
|
import { CalendarWeek, ClockHistory, Copy, Download, Eraser, Plus, Clock, Send, Filter, CalendarCheck, Check } from "react-bootstrap-icons";
|
||||||
|
import { Breadcrumb, Tabs, Tab, Dropdown, Spinner, Modal, Button } from "react-bootstrap";
|
||||||
|
|
||||||
const SentMessageList = () => {
|
const SentMessageList = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [messages, setMessages] = useState([]);
|
const [messages, setMessages] = useState([]);
|
||||||
const [datePicked, setDatePicked] = useState(new Date());
|
const [datePicked, setDatePicked] = useState(new Date());
|
||||||
|
const [showDateDropdown, setShowDateDropdown] = useState(false);
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!AuthService.canAddOrEditRoutes() && !AuthService.canViewRoutes()&&!AuthService.canAccessLegacySystem()) {
|
if (!AuthService.canAddOrEditRoutes() && !AuthService.canViewRoutes()&&!AuthService.canAccessLegacySystem()) {
|
||||||
@ -20,6 +23,14 @@ const SentMessageList = () => {
|
|||||||
})
|
})
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const cleanDate = () => {
|
||||||
|
setDatePicked(new Date());
|
||||||
|
setShowDateDropdown(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const FilterAndClose = () => {
|
||||||
|
setShowDateDropdown(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const redirectToAdmin = () => {
|
const redirectToAdmin = () => {
|
||||||
@ -31,45 +42,95 @@ const SentMessageList = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const redirectToSend = () => {
|
||||||
|
navigate(`/messages/send-message`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const customMenuDate = React.forwardRef(
|
||||||
|
({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
style={style}
|
||||||
|
className={className}
|
||||||
|
aria-labelledby={labeledBy}
|
||||||
|
>
|
||||||
|
<div className="app-main-content-fields-section margin-sm dropdown-container">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Select Date to Filter</div>
|
||||||
|
<DatePicker selected={datePicked} onChange={(v) => setDatePicked(v)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="list row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => cleanDate()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => FilterAndClose()}>Filter</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>All Sent Messages <button className="btn btn-link btn-sm" onClick={() => {redirectToAdmin()}}>Back</button>
|
<h4>All Sent Messages <button className="btn btn-link btn-sm" onClick={() => {redirectToSend()}}>Back</button>
|
||||||
</h5>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div className="mb-4">
|
<div className="app-main-content-list-func-container">
|
||||||
Pick a Date to Filter:
|
<Tabs defaultActiveKey="allSentMessages" id="sent-messages-tab">
|
||||||
</div>
|
<Tab eventKey="allSentMessages" title="All Sent Messages">
|
||||||
<div className="col-md-4 col-sm-4 col-xs-12 mb-4">
|
<table className="personnel-info-table">
|
||||||
<DatePicker selected={datePicked} onChange={(v) => setDatePicked(v)} />
|
<thead>
|
||||||
</div>
|
<tr>
|
||||||
<div className="col-md-12">
|
<th className="th-index">No.</th>
|
||||||
<table className="personnel-info-table">
|
<th>From</th>
|
||||||
<thead>
|
<th>To</th>
|
||||||
<tr>
|
<th>Message</th>
|
||||||
<th>From</th>
|
<th>Sent Time</th>
|
||||||
<th>To</th>
|
</tr>
|
||||||
<th>Message</th>
|
|
||||||
<th>Sent Time</th>
|
</thead>
|
||||||
</tr>
|
<tbody>
|
||||||
|
{
|
||||||
</thead>
|
messages && messages.filter((message) => (new Date(message?.create_date))?.toLocaleDateString() === (new Date(datePicked)).toLocaleDateString()).map((message, index) => <tr key={message.id}>
|
||||||
<tbody>
|
<td className="td-index">{index + 1}</td>
|
||||||
{
|
<td>{message?.from}</td>
|
||||||
messages && messages.filter((message) => (new Date(message?.create_date))?.toLocaleDateString() === (new Date(datePicked)).toLocaleDateString()).map(message => <tr key={message.id}>
|
<td>{message?.to}</td>
|
||||||
<td>{message?.from}</td>
|
<td>{message?.content}</td>
|
||||||
<td>{message?.to}</td>
|
<td>{`${new Date(message?.create_date)?.toLocaleDateString()} ${new Date(message?.create_date)?.toLocaleTimeString()}`}</td>
|
||||||
<td>{message?.content}</td>
|
</tr>)
|
||||||
<td>{`${new Date(message?.create_date)?.toLocaleDateString()} ${new Date(message?.create_date)?.toLocaleTimeString()}`}</td>
|
}
|
||||||
</tr>)
|
</tbody>
|
||||||
}
|
</table>
|
||||||
</tbody>
|
</Tab>
|
||||||
</table>
|
</Tabs>
|
||||||
|
<div className="list-func-panel">
|
||||||
|
<Dropdown
|
||||||
|
key={'sent-date'}
|
||||||
|
id="sent-date"
|
||||||
|
className="me-2"
|
||||||
|
show={showDateDropdown}
|
||||||
|
onToggle={() => setShowDateDropdown(!showDateDropdown)}
|
||||||
|
autoClose={false}
|
||||||
|
>
|
||||||
|
<Dropdown.Toggle variant="primary">
|
||||||
|
<CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to Filter
|
||||||
|
</Dropdown.Toggle>
|
||||||
|
<Dropdown.Menu as={customMenuDate}/>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { AuthService, MessageService } from "../../services";
|
import { AuthService, MessageService } from "../../services";
|
||||||
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||||
|
|
||||||
const UpdateMessage = () => {
|
const UpdateMessage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -55,44 +56,73 @@ const UpdateMessage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="list row mb-4">
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>General</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>
|
||||||
|
Messaging
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<div className="col-md-12 text-primary">
|
<div className="col-md-12 text-primary">
|
||||||
<h5>Update Message <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
|
<h4>
|
||||||
|
Update Message Template <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="list row mb-4">
|
<div className="app-main-content-list-container">
|
||||||
<div className="col-md-4 mb-4">
|
<div className="app-main-content-list-func-container">
|
||||||
<div>Message Group (*):</div>
|
<Tabs defaultActiveKey="messageCreation" id="message-template-tab">
|
||||||
<select value={messageGroup} onChange={e => setMessageGroup(e.target.value)} required>
|
<Tab eventKey="messageCreation" title="Update Message Template">
|
||||||
<option value=""></option>
|
<div className="app-main-content-fields-section">
|
||||||
<option value={1}>1</option>
|
<div className="me-4">
|
||||||
<option value={2}>2</option>
|
<div className="field-label">Message Group
|
||||||
<option value={3}>3</option>
|
<span className="required">*</span>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
<select value={messageGroup} onChange={e => setMessageGroup(e.target.value)} required>
|
||||||
<div className="col-md-4 mb-4">
|
<option value=""></option>
|
||||||
<div>Message Name:</div> <input type="text" value={messageName || ''} onChange={e => setMessageName(e.target.value)}/>
|
<option value={1}>1</option>
|
||||||
</div>
|
<option value={2}>2</option>
|
||||||
<div className="col-md-4 mb-4">
|
<option value={3}>3</option>
|
||||||
<div>Language:</div>
|
</select>
|
||||||
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
</div>
|
||||||
<option value=""></option>
|
<div className="me-4">
|
||||||
<option value="English">English</option>
|
<div className="field-label">Message Name
|
||||||
<option value="Chinese">Chinese</option>
|
<span className="required">*</span>
|
||||||
<option value="Vietnamese">Vietnamese</option>
|
</div>
|
||||||
<option value="Korean">Korean</option>
|
<input type="text" value={messageName || ''} onChange={e => setMessageName(e.target.value)}/>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 mb-4">
|
<div className="app-main-content-fields-section">
|
||||||
<div>Message Title:</div> <input type="text" value={messageTitle || ''} onChange={e => setMessageTitle(e.target.value)}/>
|
<div className="me-4">
|
||||||
</div>
|
<div className="field-label">Language
|
||||||
<div className="col-md-12 mb-4">
|
</div>
|
||||||
<div>Message Body:</div> <textarea value={messageBody || ''} onChange={e => setMessageBody(e.target.value)}/>
|
<select value={language} onChange={e => setLanguage(e.target.value)}>
|
||||||
</div>
|
<option value=""></option>
|
||||||
</div>
|
<option value="English">English</option>
|
||||||
<div className="list row mb-5">
|
<option value="Chinese">Chinese</option>
|
||||||
<div className="col-md-6 col-sm-6 col-xs-12">
|
<option value="Vietnamese">Vietnamese</option>
|
||||||
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveMessage()}> Save </button>
|
<option value="Korean">Korean</option>
|
||||||
<button className="btn btn-default btn-sm mb-2" onClick={() => redirectTo()}> Cancel </button>
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Message Title
|
||||||
|
</div>
|
||||||
|
<input type="text" value={messageTitle || ''} onChange={e => setMessageTitle(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="app-main-content-fields-section">
|
||||||
|
<div className="me-4">
|
||||||
|
<div className="field-label">Message Body
|
||||||
|
</div>
|
||||||
|
<textarea value={messageBody || ''} onChange={e => setMessageBody(e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
||||||
|
<button className="btn btn-primary btn-sm float-right" onClick={() => saveMessage()}> Save </button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1139,7 +1139,7 @@ const RoutesDashboard = () => {
|
|||||||
className="me-2"
|
className="me-2"
|
||||||
show={showDateDropdown}
|
show={showDateDropdown}
|
||||||
onToggle={() => setShowDateDropdown(!showDateDropdown)}
|
onToggle={() => setShowDateDropdown(!showDateDropdown)}
|
||||||
autoClose="outside"
|
autoClose={false}
|
||||||
>
|
>
|
||||||
<Dropdown.Toggle variant="primary">
|
<Dropdown.Toggle variant="primary">
|
||||||
<CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
|
<CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
|
||||||
@ -1152,7 +1152,7 @@ const RoutesDashboard = () => {
|
|||||||
className="me-2"
|
className="me-2"
|
||||||
show={showFilterDropdown}
|
show={showFilterDropdown}
|
||||||
onToggle={() => setShowFilterDropdown(!showFilterDropdown)}
|
onToggle={() => setShowFilterDropdown(!showFilterDropdown)}
|
||||||
autoClose="outside"
|
autoClose={false}
|
||||||
>
|
>
|
||||||
<Dropdown.Toggle variant="primary">
|
<Dropdown.Toggle variant="primary">
|
||||||
<Filter size={16} className="me-2"></Filter>Filter
|
<Filter size={16} className="me-2"></Filter>Filter
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user