Merge branch 'enable-and-active-jobs' of WrenchBoard/Users-Wrench into master

This commit is contained in:
2023-05-30 02:34:59 +00:00
committed by Gogs
6 changed files with 186 additions and 58 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

-10
View File
@@ -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();
+72 -10
View File
@@ -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>
); );
+42 -15
View File
@@ -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" },
];
+68 -23
View File
@@ -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}
+4
View File
@@ -788,3 +788,7 @@ TODO: Responsive ===========================
.edit-popup{ .edit-popup{
top: 75px; top: 75px;
} }
.job-popup{
top: 55px;
}