Completed
Push — master ( eb6aec...09e565 )
by Daniel
26s queued 12s
created

src/components/JobListings/JobListings.tsx   A

Complexity

Total Complexity 4
Complexity/F 0

Size

Lines of Code 198
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 4
eloc 162
mnd 4
bc 4
fnc 0
dl 0
loc 198
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { useState, useEffect } from "react";
2
3
import Pagination from "rc-pagination";
4
import { Button, Panel, Loader } from "@navikt/ds-react";
5
6
import Modal from "react-modal";
7
import { ToastContainer, toast } from "react-toastify";
8
9
import JobModalContent from "../JobModalContent/JobModalContent";
10
import SavedJobs from "../SavedJobs/SavedJobs";
11
12
import { formatDate } from "../../assets/utils/functions";
13
import { useStoreActions, useStoreState } from "../../assets/utils/hooks";
14
import locale from "../../assets/locale/localenb_NO";
15
16
import styles from "./JobListings.module.scss";
17
import "react-toastify/dist/ReactToastify.css";
18
import "rc-pagination/assets/index.css";
19
20
import { IModalContent } from "./JobListings.interface";
21
22
const JobListings: React.FC = () => {
23
  const [loading, setLoading] = useState<boolean>(true);
24
  const [modalItems, setModalItems] = useState<IModalContent[]>();
25
  const [pageNumber, setPageNumber] = useState<number>(1);
26
  const [modalIsOpen, setModalIsOpen] = useState<boolean>(false);
27
28
  const jobsPerPage = 10;
29
  const pagesVisited = pageNumber * jobsPerPage;
30
31
  const remoteError = useStoreState((state) => state.jobs.error);
32
  const jobItems = useStoreState((state) => state.jobs.jobItems);
33
  const jobModalItems = useStoreState((state) => state.jobs.jobModalItems);
34
  const addJob = useStoreActions((actions) => actions.jobs.addJob);
35
36
  const fetchRemoteJobs = useStoreActions(
37
    (actions) => actions.jobs.fetchRemoteJobs
38
  );
39
40
  const jobExistsToast = () => toast.error("Jobb er allerede lagret ...");
41
  const errorFetchingJobsToast = (errorMessage: string) =>
42
    toast.error(`Feil ved henting av ekstern data ${errorMessage}`);
43
  const jobExists = (search: string) =>
44
    jobModalItems.findIndex((value) => value.title === search);
45
46
  // Changes page to the current page (on click)
47
  const changePage = (page: number) => {
48
    setPageNumber(page);
49
  };
50
51
  const handleOpenModalClick = (
52
    description: string,
53
    extent: string,
54
    name: string,
55
    applicationDue: string
56
  ) => {
57
    setModalItems([
58
      {
59
        description,
60
        name,
61
        extent,
62
        applicationDue,
63
      },
64
    ]);
65
  };
66
67
  const closeModal = () => {
68
    setModalIsOpen(false);
69
  };
70
71
  useEffect(() => {
72
    if (remoteError.length > 0) {
73
      errorFetchingJobsToast(remoteError);
74
    }
75
  }, [remoteError]);
76
77
  useEffect(() => {
78
    if (modalItems && modalItems[0].name.length) {
79
      setModalIsOpen(true);
80
    }
81
  }, [modalItems]);
82
83
  useEffect(() => {
84
    fetchRemoteJobs();
85
  }, [fetchRemoteJobs]);
86
87
  useEffect(() => {
88
    if (jobItems.length) {
89
      Modal.setAppElement("#root");
90
      setLoading(false);
91
    } else {
92
      setLoading(true);
93
    }
94
  }, [jobItems]);
95
96
  return (
97
    <div>
98
      <h1 className={styles.header}>NAV Jobb Utforsker</h1>
99
      <SavedJobs handleOpenModalClick={handleOpenModalClick} />
100
      <ToastContainer position="top-center" />
101
      <div id="jobcontainer" className={styles.container}>
102
        <Modal
103
          isOpen={modalIsOpen}
104
          onRequestClose={closeModal}
105
          contentLabel="title"
106
        >
107
          {modalItems && (
108
            <JobModalContent
109
              name={modalItems[0].name}
110
              description={modalItems[0].description}
111
              extent={modalItems[0].extent}
112
              applicationDue={modalItems[0].applicationDue}
113
              closeModal={closeModal}
114
            />
115
          )}
116
        </Modal>
117
        {!loading &&
118
          jobItems
119
            .slice(pagesVisited, pagesVisited + jobsPerPage)
120
            .map(
121
              ({
122
                uuid,
123
                title,
124
                employer: { name },
125
                published,
126
                description,
127
                extent,
128
                applicationDue,
129
              }) => (
130
                <Panel key={uuid} className={styles.panel} border>
131
                  <span className={`${styles.panelSpan} ${styles.title}`}>
132
                    {title}
133
                  </span>
134
                  <span className={styles.panelSpan}>
135
                    {name.length && name}
136
                  </span>
137
                  <span className={styles.panelSpan}>
138
                    Publisert: {published && formatDate(published)}
139
                  </span>
140
                  <span className={styles.panelButton}>
141
                    <Button
142
                      className={styles.hovedKnapp}
143
                      onClick={() =>
144
                        handleOpenModalClick(
145
                          description,
146
                          extent,
147
                          name,
148
                          applicationDue
149
                        )
150
                      }
151
                    >
152
                      Vis
153
                    </Button>
154
                    <Button
155
                      className={styles.sekundKnapp}
156
                      onClick={() => {
157
                        // Check if we try to add an existing job, if yes, show error message
158
                        if (jobExists(title) === -1) {
159
                          addJob({
160
                            title,
161
                            description,
162
                            extent,
163
                            name,
164
                            applicationDue,
165
                          });
166
                        } else {
167
                          jobExistsToast();
168
                        }
169
                      }}
170
                    >
171
                      Lagre
172
                    </Button>
173
                  </span>
174
                </Panel>
175
              )
176
            )}
177
      </div>
178
      {!loading && (
179
        <Pagination
180
          className={styles.pagination}
181
          current={pageNumber}
182
          total={jobItems.length - 10}
183
          pageSize={jobsPerPage}
184
          locale={locale}
185
          onChange={(page) => changePage(page)}
186
        />
187
      )}
188
      {loading && !remoteError && (
189
        <div className={styles.loader}>
190
          <Loader />
191
        </div>
192
      )}
193
    </div>
194
  );
195
};
196
197
export default JobListings;
198