Merge branch 'enable-and-active-jobs' of WrenchBoard/Users-Wrench into master
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -36,16 +36,6 @@ const validationSchema = Yup.object().shape({
|
|||||||
.required("Timeline is required"),
|
.required("Timeline is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// let initialValues = {
|
|
||||||
// // initial values for formik
|
|
||||||
// country: "NG",
|
|
||||||
// price: 0,
|
|
||||||
// title: "",
|
|
||||||
// description: "",
|
|
||||||
// job_detail: "",
|
|
||||||
// timeline_days: "",
|
|
||||||
// };
|
|
||||||
|
|
||||||
function AddJob() {
|
function AddJob() {
|
||||||
const ApiCall = new usersService();
|
const ApiCall = new usersService();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import React, {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import profile from "../../assets/images/profile-info-profile.png";
|
import profile from "../../assets/images/profile-info-profile.png";
|
||||||
|
import qrSample from "../../assets/images/qr-sample.png";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import FamilyTasks from "./FamilyTasks";
|
import FamilyTasks from "./FamilyTasks";
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ export default function FamilyManageTabs({
|
|||||||
accountDetails={accountDetails}
|
accountDetails={accountDetails}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-3 p-6 h-full w-full">
|
<div className="col-span-3 justify-self-end h-full w-full">
|
||||||
<div className="flex flex-col w-full">
|
<div className="flex flex-col w-full">
|
||||||
<ul className="flex-[0.1] flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
<ul className="flex-[0.1] flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
||||||
{tabs.map(({ name, id }) => (
|
{tabs.map(({ name, id }) => (
|
||||||
@@ -130,7 +131,12 @@ export default function FamilyManageTabs({
|
|||||||
<LoadingSpinner size="8" color="sky-blue" />
|
<LoadingSpinner size="8" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{name === "Tasks" && <FamilyTasks className={className} loader={loader}/>}
|
{name === "Tasks" && (
|
||||||
|
<FamilyTasks
|
||||||
|
className={className}
|
||||||
|
loader={loader}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{name === "Account" && (
|
{name === "Account" && (
|
||||||
<Account familyDetails={familyDetails} />
|
<Account familyDetails={familyDetails} />
|
||||||
)}
|
)}
|
||||||
@@ -212,15 +218,71 @@ function ProfileInfo({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Account({ familyDetails }) {
|
function Account({ familyDetails }) {
|
||||||
|
const handlePrint = () => {
|
||||||
|
const printableContent = `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
/* Add your desired styles here */
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class"update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow"></div>
|
||||||
|
<h1>Family member details</h1>
|
||||||
|
<p>Username: ${familyDetails?.username}</p>
|
||||||
|
<p>Password: ${familyDetails?.pin}</p>
|
||||||
|
<img src="${qrSample}" alt="QR Code" />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const printWindow = window.open('', '', 'width=800,height=700');
|
||||||
|
printWindow.document.open();
|
||||||
|
printWindow.document.write(printableContent);
|
||||||
|
printWindow.document.close();
|
||||||
|
|
||||||
|
printWindow.onload = () => {
|
||||||
|
printWindow.print();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full lg:min-h-[400px] h-full flex items-center justify-center">
|
<div className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center">
|
||||||
<div className="flex flex-col">
|
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
||||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
<div className="flex items-center justify-around h-[380px]">
|
||||||
Username: <span className="ml-2 normal-case">{familyDetails?.username}</span>
|
<div className="flex flex-col">
|
||||||
</h2>
|
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
Username:{" "}
|
||||||
Pin: <span className="ml-2 normal-case">{familyDetails?.pin}</span>
|
<span className="ml-2 normal-case">
|
||||||
</h2>
|
{familyDetails?.username}
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
|
Pin:{" "}
|
||||||
|
<span className="ml-2 normal-case">{familyDetails?.pin}</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="text-5xl text-gray-400 opacity-20 font-bold">
|
||||||
|
or
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div className="max-w-[200px]">
|
||||||
|
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
|
||||||
|
Scan the code from mobile app
|
||||||
|
</p>
|
||||||
|
<img
|
||||||
|
src={qrSample}
|
||||||
|
alt="qr-sample"
|
||||||
|
className="h-[200px] w-[200px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="h-[50px] w-full flex justify-center items-center">
|
||||||
|
<button className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center" onClick={handlePrint}>
|
||||||
|
Print
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import ModalCom from "../Helpers/ModalCom";
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
import { Form, Formik } from "formik";
|
import { Field, Form, Formik } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
@@ -245,20 +245,34 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-6">
|
||||||
<InputCom
|
<div className={`flex items-center justify-between mb-2.5`}>
|
||||||
fieldClass="px-6"
|
<label
|
||||||
label="Timeline"
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||||
labelClass="tracking-wide"
|
htmlFor="timeline_days"
|
||||||
inputBg="bg-slate-100"
|
>
|
||||||
inputClass=" input-curve lg border border-[#dce4e9]"
|
Timeline
|
||||||
type="text"
|
<span className="text-green-700 text-sm tracking-wide">
|
||||||
name="timeline_days"
|
- Expected duration of this task
|
||||||
spanTag=" - Expected duration of this task"
|
</span>
|
||||||
// placeholder="Please Enter Detail Description of Job"
|
</label>
|
||||||
value={props.values.timeline_days}
|
</div>
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
<Field
|
||||||
/>
|
component="select"
|
||||||
|
name="timeline_days"
|
||||||
|
className="input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none"
|
||||||
|
value={props.values.timeline_days}
|
||||||
|
>
|
||||||
|
<option value="">Select Duration</option>
|
||||||
|
{publicArray.map(({ name, duration }, idx) => (
|
||||||
|
<option
|
||||||
|
className="text-slate-500 text-lg"
|
||||||
|
value={duration}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Field>
|
||||||
{props.errors.timeline_days &&
|
{props.errors.timeline_days &&
|
||||||
props.touched.timeline_days && (
|
props.touched.timeline_days && (
|
||||||
<p className="text-sm text-red-500">
|
<p className="text-sm text-red-500">
|
||||||
@@ -316,3 +330,16 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default EditJobPopOut;
|
export default EditJobPopOut;
|
||||||
|
|
||||||
|
const publicArray = [
|
||||||
|
{ duration: 1, name: "1 day" },
|
||||||
|
{ duration: 2, name: "2 days" },
|
||||||
|
{ duration: 3, name: "3 days" },
|
||||||
|
{ duration: 4, name: "4 days" },
|
||||||
|
{ duration: 5, name: "5 days" },
|
||||||
|
{ duration: 6, name: "6 days" },
|
||||||
|
{ duration: 7, name: "1 week" },
|
||||||
|
{ duration: 14, name: "2 weeks" },
|
||||||
|
{ duration: 21, name: "3 weeks" },
|
||||||
|
{ duration: 28, name: "4 weeks" },
|
||||||
|
];
|
||||||
|
|||||||
@@ -69,28 +69,49 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let [textArea, setTextArea] = useState(details?.job_detail);
|
let [textArea, setTextArea] = useState(details?.job_detail);
|
||||||
const [errMsg, setErrMsg] = useState("")
|
const [errMsg, setErrMsg] = useState({
|
||||||
|
deliveryDetail: "",
|
||||||
|
jobFields: {
|
||||||
|
family: "",
|
||||||
|
public: "",
|
||||||
|
individual: "",
|
||||||
|
group: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const handleInputChange = ({ target: { value } }) => {
|
const handleInputChange = ({ target: { value } }) => {
|
||||||
setTextArea(value);
|
setTextArea(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const errorHandler = ({target: {name}}) => {
|
const errorHandler = ({ target: { name } }) => {
|
||||||
|
try {
|
||||||
}
|
if (name === "family")
|
||||||
|
setErrMsg({ jobFields: { family: "please select a family member" } });
|
||||||
|
else if (name === "public")
|
||||||
|
setErrMsg({ jobFields: { public: "please select duration" } });
|
||||||
|
else if (name === "individual")
|
||||||
|
setErrMsg({ jobFields: { individual: "please enter email" } });
|
||||||
|
else if (name === "group")
|
||||||
|
setErrMsg({ jobFields: { group: "please select a family member" } });
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
setErrMsg({ jobFields: "" });
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const jobFieldHandler = async (values, helpers) => {
|
const jobFieldHandler = async (values, helpers) => {
|
||||||
let { job_id, job_uid } = details;
|
let { job_id, job_uid } = details;
|
||||||
|
|
||||||
if(!textArea) {
|
if (!textArea) {
|
||||||
setErrMsg("delivery detail is required!")
|
setErrMsg({ deliveryDetail: "delivery detail is required!" });
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let jobReq = {
|
let jobReq = {
|
||||||
job_id,
|
job_id,
|
||||||
job_uid,
|
job_uid,
|
||||||
job_description: textArea
|
job_description: textArea,
|
||||||
};
|
};
|
||||||
let reqData;
|
let reqData;
|
||||||
|
|
||||||
@@ -131,8 +152,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
};
|
};
|
||||||
setLoader({ jobFields: { group: true } });
|
setLoader({ jobFields: { group: true } });
|
||||||
} else {
|
} else {
|
||||||
setErrMsg("err herre")
|
return;
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -148,7 +168,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation} className="edit-popup">
|
<ModalCom action={onClose} situation={situation} className="job-popup">
|
||||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||||
<h1 className="text-base md:text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
<h1 className="text-base md:text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
@@ -218,7 +238,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
value={textArea}
|
value={textArea}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
{/* <p>{errMsg}</p> */}
|
<p>{errMsg.deliveryDetail}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -231,7 +251,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
>
|
>
|
||||||
{(props) => {
|
{(props) => {
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form className="mb-4">
|
||||||
{/* Assign to Family */}
|
{/* Assign to Family */}
|
||||||
<JobFieldInput
|
<JobFieldInput
|
||||||
label="Assign to family"
|
label="Assign to family"
|
||||||
@@ -242,8 +262,14 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
btnText="Assign to family"
|
btnText="Assign to family"
|
||||||
optionText="Select Family"
|
optionText="Select Family"
|
||||||
loader={loader?.jobFields.family}
|
loader={loader?.jobFields.family}
|
||||||
|
errorHandler={errorHandler}
|
||||||
/>
|
/>
|
||||||
{/* <p>{errMsg}</p> */}
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.family === "" && (
|
||||||
|
<span>{errMsg.jobFields.family}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -256,7 +282,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
>
|
>
|
||||||
{(props) => {
|
{(props) => {
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form className="mb-4">
|
||||||
{/* Offer this job to public input */}
|
{/* Offer this job to public input */}
|
||||||
<JobFieldInput
|
<JobFieldInput
|
||||||
label="Offer this job to public"
|
label="Offer this job to public"
|
||||||
@@ -267,8 +293,14 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
btnText="Show Task to Public"
|
btnText="Show Task to Public"
|
||||||
optionText="Select Duration"
|
optionText="Select Duration"
|
||||||
loader={loader?.jobFields.public}
|
loader={loader?.jobFields.public}
|
||||||
|
errorHandler={errorHandler}
|
||||||
/>
|
/>
|
||||||
{/* <p>{errMsg}</p> */}
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.public === "" && (
|
||||||
|
<span>{errMsg.jobFields.public}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -281,7 +313,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
>
|
>
|
||||||
{(props) => {
|
{(props) => {
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form className="mb-4">
|
||||||
{/* Offer this job to individual input */}
|
{/* Offer this job to individual input */}
|
||||||
<JobFieldInput
|
<JobFieldInput
|
||||||
label="Offer this job to individual"
|
label="Offer this job to individual"
|
||||||
@@ -292,8 +324,14 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
inputHandler={props?.handleChange}
|
inputHandler={props?.handleChange}
|
||||||
btnText="Send Offer to Individual"
|
btnText="Send Offer to Individual"
|
||||||
loader={loader?.jobFields.individual}
|
loader={loader?.jobFields.individual}
|
||||||
|
errorHandler={errorHandler}
|
||||||
/>
|
/>
|
||||||
{/* <p>{errMsg}</p> */}
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.individual === "" && (
|
||||||
|
<span>{errMsg.jobFields.individual}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -306,7 +344,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
>
|
>
|
||||||
{(props) => {
|
{(props) => {
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form className="mb-4">
|
||||||
{/* Offer this job to your group input */}
|
{/* Offer this job to your group input */}
|
||||||
<JobFieldInput
|
<JobFieldInput
|
||||||
label="Offer this job to your Group"
|
label="Offer this job to your Group"
|
||||||
@@ -316,13 +354,18 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
btnText="Send Order to Group"
|
btnText="Send Order to Group"
|
||||||
optionText="Group"
|
optionText="Group"
|
||||||
loader={loader?.jobFields.group}
|
loader={loader?.jobFields.group}
|
||||||
|
errorHandler={errorHandler}
|
||||||
/>
|
/>
|
||||||
{/* <p>{errMsg}</p> */}
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.group === "" && (
|
||||||
|
<span>{errMsg.jobFields.group}</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Formik>
|
</Formik>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{/* END OF ACTION SECTION */}
|
{/* END OF ACTION SECTION */}
|
||||||
</div>
|
</div>
|
||||||
@@ -346,11 +389,12 @@ const JobFieldInput = ({
|
|||||||
btnText,
|
btnText,
|
||||||
parentClass,
|
parentClass,
|
||||||
optionText,
|
optionText,
|
||||||
|
errorHandler,
|
||||||
loader,
|
loader,
|
||||||
data,
|
data,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="field w-full p-3 mb-6 bg-red-50 rounded-md">
|
<div className="field w-full p-3 mb-2 bg-red-50 rounded-md">
|
||||||
{select && (
|
{select && (
|
||||||
<>
|
<>
|
||||||
<div className={`input-com ${parentClass}`}>
|
<div className={`input-com ${parentClass}`}>
|
||||||
@@ -407,7 +451,7 @@ const JobFieldInput = ({
|
|||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label={label}
|
label={label}
|
||||||
labelClass="tracking-wide"
|
labelClass="tracking-wide"
|
||||||
type="text"
|
type="email"
|
||||||
name={inputName}
|
name={inputName}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={value}
|
value={value}
|
||||||
@@ -421,6 +465,7 @@ const JobFieldInput = ({
|
|||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
name={inputName}
|
name={inputName}
|
||||||
|
onClick={errorHandler}
|
||||||
className="px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md"
|
className="px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md"
|
||||||
>
|
>
|
||||||
{loader ? <LoadingSpinner size={5} /> : btnText}
|
{loader ? <LoadingSpinner size={5} /> : btnText}
|
||||||
|
|||||||
@@ -787,4 +787,8 @@ TODO: Responsive ===========================
|
|||||||
|
|
||||||
.edit-popup{
|
.edit-popup{
|
||||||
top: 75px;
|
top: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-popup{
|
||||||
|
top: 55px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user