PHP 8.2.30
Preview: JobListingsSectionCustomize.jsx Size: 15.71 KB
/proc/thread-self/root/home/byroehnu/easetack.com/resources/js/Admin/Components/SectionCustomize/JobListingsSectionCustomize.jsx

import React, { useEffect, useState } from "react"
import AdvanceCustomize from "@/Admin/Components/SectionCustomize/AdvanceCustomize"
import { useDispatch } from "react-redux"
import { useSelector } from "react-redux"
import { updatePageSection, updatePageAdvancedSettings } from "@/Redux/features/pages/Page/page"
import { produce } from "immer"
import { Icon } from "@iconify/react"

export default function JobListingsSectionCustomize({ index }) {
    const { currentLang, pageData } = useSelector((state) => state.pages)
    const [tab, setTab] = useState("general")
    const dispatch = useDispatch()
    const [sectionData, setSectionData] = useState({})
    const [advancedData, setAdvancedData] = useState({})
    const [data, setData] = useState({})
    const [layout, setLayout] = useState(false)

    const advancedCallback = (data) => {
        if (index) {
            setAdvancedData(data)
            dispatch(updatePageAdvancedSettings({ data, index }))
        }
    }

    // List Item Accordion
    const [openIndex, setOpenIndex] = useState(0)
    const handleToggle = (index) => {
        setOpenIndex((prevIndex) => (prevIndex === index ? -1 : index))
    }

    // Remove Job
    const removeJob = (removeIndex) => {
        setData(
            produce((draft) => {
                draft.job_list = draft.job_list.filter((_, index) => index !== removeIndex)
            })
        )
    }

    // Clone Job
    const cloneJob = (cloneIndex) => {
        setData(
            produce((draft) => {
                const newList = [...draft.job_list]
                const clonedItem = { ...newList[cloneIndex] }
                newList.splice(cloneIndex + 1, 0, clonedItem)
                draft.job_list = newList
                setOpenIndex(cloneIndex + 1)
            })
        )
    }

    // Add New Job
    const addNewJob = () => {
        setData(
            produce((draft) => {
                draft.job_list.push({
                    job_title: "",
                    job_description: "",
                    job_duration: "",
                    job_status: "",
                    job_action_text: "",
                    job_action_url: ""
                })
                setOpenIndex(draft.job_list.length - 1)
            })
        )
    }

    // conditional render
    let customizer = ""
    if (data.layout === "1") {
        customizer = (
            <>
                <div className="form-group">
                    <label>Section Title</label>
                    <input
                        type="text"
                        value={data.section_title}
                        onChange={(e) => setData({ ...data, section_title: e.target.value })}
                        className="form-control"
                    />
                </div>
                <div className="form-group">
                    <label>Section Subtitle</label>
                    <input
                        className="form-control"
                        value={data.section_subtitle}
                        onChange={(e) =>
                            setData({
                                ...data,
                                section_subtitle: e.target.value
                            })
                        }
                    />
                </div>
                <div className="cs_loop_list">
                    <label>Job List</label>
                    <div className="cs_loop_list_in">
                        {data.job_list?.map((item, index) => (
                            <div className="cs_loop_item" key={index}>
                                <div className="cs_loop_item_head">
                                    <span onClick={() => handleToggle(index)}>
                                        <span>{item.job_title ? item.job_title : "List Item"}</span>
                                    </span>
                                    <div className="cs_loop_item_control_btns">
                                        <button className="cs_clone_loop_item" onClick={() => cloneJob(index)}>
                                            <Icon icon="lucide:copy" width="18" height="18" />
                                        </button>
                                        {data.job_list.length === 1 ? (
                                            ""
                                        ) : (
                                            <button className="cs_remove_loop_item" onClick={() => removeJob(index)}>
                                                <Icon icon="lucide:x" width="18" height="18" />
                                            </button>
                                        )}
                                    </div>
                                </div>
                                {openIndex === index && (
                                    <div className="cs_loop_item_body">
                                        <div className="form-group">
                                            <label>Job Title</label>
                                            <input
                                                type="text"
                                                value={item.job_title}
                                                onChange={(e) => {
                                                    setData(
                                                        produce((draft) => {
                                                            draft.job_list[index].job_title = e.target.value
                                                        })
                                                    )
                                                }}
                                                className="form-control"
                                            />
                                        </div>
                                        <div className="form-group">
                                            <label>Job Description</label>
                                            <textarea
                                                cols="30"
                                                rows="10"
                                                value={item.job_description}
                                                onChange={(e) => {
                                                    setData(
                                                        produce((draft) => {
                                                            draft.job_list[index].job_description = e.target.value
                                                        })
                                                    )
                                                }}
                                                className="form-control"
                                            />
                                        </div>
                                        <div className="form-group">
                                            <label>Job Duration</label>
                                            <input
                                                type="text"
                                                value={item.job_duration}
                                                onChange={(e) => {
                                                    setData(
                                                        produce((draft) => {
                                                            draft.job_list[index].job_duration = e.target.value
                                                        })
                                                    )
                                                }}
                                                className="form-control"
                                            />
                                        </div>
                                        <div className="form-group">
                                            <label>Job Status</label>
                                            <input
                                                type="text"
                                                value={item.job_status}
                                                onChange={(e) => {
                                                    setData(
                                                        produce((draft) => {
                                                            draft.job_list[index].job_status = e.target.value
                                                        })
                                                    )
                                                }}
                                                className="form-control"
                                            />
                                        </div>
                                        <div className="row row_space_10">
                                            <div className="col-sm-6">
                                                <div className="form-group">
                                                    <label>Action Text</label>
                                                    <input
                                                        type="text"
                                                        value={item.job_action_text}
                                                        onChange={(e) => {
                                                            setData(
                                                                produce((draft) => {
                                                                    draft.job_list[index].job_action_text = e.target.value
                                                                })
                                                            )
                                                        }}
                                                        className="form-control"
                                                    />
                                                </div>
                                            </div>
                                            <div className="col-sm-6">
                                                <div className="form-group">
                                                    <label>Action URL</label>
                                                    <input
                                                        type="text"
                                                        value={item.job_action_url}
                                                        onChange={(e) => {
                                                            setData(
                                                                produce((draft) => {
                                                                    draft.job_list[index].job_action_url = e.target.value
                                                                })
                                                            )
                                                        }}
                                                        className="form-control"
                                                    />
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                )}
                            </div>
                        ))}
                        <div className="cs_loop_list_btn">
                            <button className="btn btn-sm btn-primary" onClick={addNewJob}>
                                Add new
                            </button>
                        </div>
                    </div>
                </div>
            </>
        )
    }
    useEffect(() => {
        if (index) {
            setData({
                layout: sectionData?.data?.layout ?? "1",
                section_title: sectionData?.data?.section_title ?? "",
                section_subtitle: sectionData?.data?.section_subtitle ?? "",
                job_list: sectionData?.data?.job_list ?? [
                    {
                        job_title: "",
                        job_description: "",
                        job_duration: "",
                        job_status: "",
                        job_action_text: "",
                        job_action_url: ""
                    }
                ]
            })
        }
    }, [currentLang, sectionData, index])

    useEffect(() => {
        if (index) {
            setSectionData(pageData[currentLang][index])
        }
    }, [index, currentLang])

    useEffect(() => {
        if (Object.keys(data).length !== 0 && index) {
            dispatch(updatePageSection({ data, index }))
        }
    }, [data, index])

    useEffect(() => {
        if (index) {
            setAdvancedData(pageData[currentLang][index].advanced)
        }
    }, [index, currentLang, pageData])

    return (
        <>
            <div className="cs_tab_wrap">
                <span className={`cs_tab_item${tab === "general" ? " active" : ""}`} onClick={() => setTab("general")}>
                    <Icon icon="lucide:pencil" width="18" height="18" /> General
                </span>
                <span className={`cs_tab_item${tab === "advance" ? " active" : ""}`} onClick={() => setTab("advance")}>
                    <Icon icon="lucide:settings" width="18" height="18" />
                    Advance
                </span>
            </div>
            {tab === "general" ? (
                <>
                    <div className="cs_design_layout_box">
                        <div className={`cs_design_layout_select ${layout ? "active" : ""}`}>
                            <label>Design Layout</label>
                            <div className="cs_design_layout_toggle_btn" onClick={() => setLayout(!layout)}>
                                Job Listings Style {data.layout}
                                <Icon icon="lucide:chevron-down" width="17" height="17" />
                            </div>
                        </div>
                        {layout && (
                            <div className="cs_section_images">
                                {["1"].map((value) => (
                                    <div key={value} className="cs_section_image" onClick={() => setLayout(!layout)}>
                                        <input
                                            type="radio"
                                            id={`layout-${value}`}
                                            name="layout"
                                            value={value}
                                            checked={data.layout === value}
                                            onChange={(e) =>
                                                setData({
                                                    ...data,
                                                    layout: e.target.value
                                                })
                                            }
                                            className="form-check-input"
                                        />
                                        <div className="cs_section_image_in">
                                            <img src={`/static/sections/job_listings/style_${value}.jpg`} alt="Thumb" />
                                            <label htmlFor={`layout-${value}`}>Job Listings Style {value}</label>
                                        </div>
                                    </div>
                                ))}
                            </div>
                        )}
                    </div>
                    {customizer}
                </>
            ) : (
                <AdvanceCustomize advancedCallback={advancedCallback} currentSection={advancedData} />
            )}
        </>
    )
}

Directory Contents

Dirs: 0 × Files: 46

Name Size Perms Modified Actions
45.25 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
16.62 KB lrw-rw-rw- 2025-05-08 11:48:26
Edit Download
36.11 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
8.64 KB lrw-rw-rw- 2025-04-25 15:28:35
Edit Download
14.61 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
16.47 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
12.45 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
19.87 KB lrw-rw-rw- 2025-04-20 06:37:35
Edit Download
72.27 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
43.25 KB lrw-rw-rw- 2025-05-08 11:48:26
Edit Download
40.14 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
13.56 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
1.47 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
2.90 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
1.57 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
17.25 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
24.17 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
5.94 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
10.42 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
8.46 KB lrw-rw-rw- 2025-04-25 15:52:04
Edit Download
5.21 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
84.26 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
56.96 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
729 B lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
15.71 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
4.80 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
14.15 KB lrw-rw-rw- 2025-04-17 09:57:57
Edit Download
14.85 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
11.61 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
12.25 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
20.19 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
17.90 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
48.19 KB lrw-rw-rw- 2025-04-22 07:42:55
Edit Download
12.22 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
74.68 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
3.64 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
7.26 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
1.22 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
11.45 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
14.36 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
28.25 KB lrw-rw-rw- 2025-05-15 11:24:11
Edit Download
46.22 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
5.24 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
10.28 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
22.10 KB lrw-rw-rw- 2025-04-08 04:12:57
Edit Download
19.77 KB lrw-rw-rw- 2025-04-22 07:42:55
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).