Source

pages/PublicNews/PublicNews.jsx

import { useState, useMemo } from "react";
import "./news.css";
import LoadingAnimation from "../Dashboard/Loading/LoadingAnimation";
import { NavLink } from "react-router-dom";
import { useGetNews } from "../../apis/News";
/**
 * Represents the PublicNews page for displaying public news.
 * @module PublicNews
 * @returns {JSX.Element} The PublicNews component.
 */
const PublicNews = () => {
  const [gridView, setGridVied] = useState(true);
  const [filterDropdown, setFilterDropdown] = useState(false);
  const [searchInput, setSearchInput] = useState("");
  const [sortBy, setSortBy] = useState("");
  const { data: news, isLoading: newsLoading } = useGetNews();
  const getNewsData = useMemo(() => {
    const temp = news?.data?.data?.results || [];
    if (searchInput) {
      const filteredList = temp.filter((contract) =>
        contract.title.toLowerCase().includes(searchInput.toLowerCase())
      );
      return filteredList.reverse();
    }
    switch (sortBy) {
      case "AZ":
        return [...temp].sort((a, b) => a.title.localeCompare(b.title));
      case "ZA":
        return [...temp]
          .sort((a, b) => a.title.localeCompare(b.title))
          .reverse();
      case "OLD":
        return [...temp].reverse();
      case "RECENT":
        return temp;
    }
    return temp;
  }, [news?.data, searchInput, sortBy]);
  /**
   * Removes HTML tags from an HTML string.
   * @function stripHTML
   * @param {string} htmlString - The HTML string to strip HTML tags from.
   * @returns {string} The HTML string with tags stripped.
   */
  function stripHTML(htmlString) {
    const regex = /<[^>]*>/g; // Regular expression to match HTML tags
    return htmlString.replace(regex, "");
  }
  /**
   * Renders the selected view of news (grid or list).
   * @function getSelectedView
   * @param {boolean} view - The selected view (grid or list).
   * @returns {JSX.Element} The rendered news view.
   */
  const getSelectedView = (view) => {
    if (view) {
      return (
        <div className="news_div">
          <div className="documents_div_for_grid_view">
            {getNewsData.map((dat, i) => {
              return (
                <div className="individual_news_card" key={i}>
                  <NavLink to={`../single/news/${dat.id}`}>
                    <div className="news_wrapper"></div>
                  </NavLink>
                  <div className="news_card_body">
                    <div className="news_thumbnail">
                      <img src={dat?.image} alt="" />
                    </div>
                  </div>

                  <div className="news_card_footer">
                    <div className="news_card_footer_content">
                      <div className="news_start_end_div">
                        <div className="start_date">
                          {/* <small>Published at: </small> */}
                          <small>{dat?.created_at}</small>
                        </div>
                      </div>
                      <h4>{dat?.title}</h4>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      );
    }
    return (
      <div className="news_div">
        <div className="documents_div_for_list_view">
          {/* no css rules for the above div class */}
          {getNewsData.map((dat, i) => {
            return (
              <div className="individual_list_news_card" key={i}>
                <NavLink to={`../single/news/${dat.id}`}>
                  <div className="news_list_card_body">
                    <div className="news_list_thumbnail">
                      <img src={dat?.image} alt="" />
                    </div>
                    <div className="news_list_card_footer">
                      <div className="news_list_card_footer_content">
                        <div className="news_start_end_div">
                          <div className="start_date">
                            <p>Published at : {dat?.created_at}</p>
                          </div>
                        </div>
                        <div>
                          <b>{dat?.title}</b>
                          <p className="mt-2 content">
                            {stripHTML(dat?.content.substring(0, 100))}...
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                </NavLink>
              </div>
            );
          })}
        </div>
      </div>
    );
  };
  if (newsLoading) {
    return <LoadingAnimation />;
  }
  return (
    <div className="public_news_container">
      <div className="news_heading flex justify-between mb-2">
        <h2 className="main-title">News</h2>
        <div className="news_search">
          <div className="left_news_search">
            <div className="search_input">
              {/* <ion-icon name="search-outline"></ion-icon> */}
              <input
                type="text"
                onChange={(e) => setSearchInput(e.target.value)}
                placeholder="Search"
              />
            </div>
          </div>
          <div className="left_news_search ">
            <ion-icon name="search"></ion-icon>
          </div>
          <div className="right_news_search">
            <div className="right_news_grid_list_view">
              <ul>
                {gridView ? (
                  <li
                    onClick={() => setGridVied(!gridView)}
                    style={{
                      background: "#53BF8A",
                      borderRadius: ".2rem",
                      color: "#ffffff",
                    }}
                  >
                    <ion-icon name="grid-outline"></ion-icon>
                  </li>
                ) : (
                  <li onClick={() => setGridVied(!gridView)}>
                    <ion-icon name="grid-outline"></ion-icon>
                  </li>
                )}
                {gridView ? (
                  <li onClick={() => setGridVied(!gridView)}>
                    <ion-icon name="list-outline"></ion-icon>
                  </li>
                ) : (
                  <li
                    onClick={() => setGridVied(!gridView)}
                    style={{
                      background: "#53BF8A",
                      borderRadius: ".2rem",
                      color: "#ffffff",
                    }}
                  >
                    <ion-icon name="list-outline"></ion-icon>
                  </li>
                )}
              </ul>
            </div>
            <div
              className="right_news_filter_div"
              onClick={() => {
                setFilterDropdown(!filterDropdown);
              }}
            >
              <p>Sort by</p>
              {filterDropdown ? (
                <ion-icon name="chevron-up-outline"></ion-icon>
              ) : (
                <ion-icon name="chevron-down-outline"></ion-icon>
              )}
              {filterDropdown && (
                <div className="news_filter_dropdown">
                  <p onClick={() => setSortBy("AZ")}>A - Z</p>
                  <p onClick={() => setSortBy("ZA")}>Z - A</p>
                  <p onClick={() => setSortBy("RECENT")}>Recent</p>
                  <p onClick={() => setSortBy("OLD")}>Oldest</p>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
      {getNewsData?.length === 0 ? (
        <div className="empty_event_container">
          <div className="event_logo">
            <ion-icon name="calendar-outline"></ion-icon>
            <h3>No events added yet</h3>
            <div className="add_new_event">
              <p>Stay tuned for updates and secure your spot today.</p>
            </div>
          </div>
        </div>
      ) : (
        <>
          <div className="navigation_for_mobile">
            <div className="left_mobile_navigation">
              <input type="text" placeholder="search" />
              <ion-icon name="search-outline"></ion-icon>
            </div>
            <div className="right_mobile_navigation">
              <ul>
                <li>
                  <ion-icon name="options"></ion-icon>
                </li>
              </ul>
            </div>
          </div>
          <div className="news_body">{getSelectedView(gridView)}</div>
        </>
      )}
    </div>
  );
};
export default PublicNews;