mirror of
https://github.com/crocofied/CoreControl.git
synced 2025-12-17 15:36:50 +00:00
useSites Hook & Searchbar & Layout component
This commit is contained in:
parent
366ad21ed1
commit
20dc406fd1
@ -3,10 +3,9 @@ import Sidebar from "@/components/Sidebar";
|
||||
import { Plus } from "lucide-react";
|
||||
import AddSite from "@/components/dialogues/AddSite";
|
||||
import Sites from "@/components/cards/Sites";
|
||||
import axios from "axios";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import Pagination from "@/components/Pagination";
|
||||
import Cookies from "js-cookie";
|
||||
import useSites from "@/hooks/useSites";
|
||||
import SearchAndLayout from "@/components/SearchAndLayout";
|
||||
|
||||
interface SitesPageProps {
|
||||
username: string;
|
||||
@ -14,40 +13,18 @@ interface SitesPageProps {
|
||||
}
|
||||
|
||||
export default function SitesPage({ username, name }: SitesPageProps) {
|
||||
const [sites, setSites] = useState([]);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemPerPage, setItemPerPage] = useState(5);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [search, setSearch] = useState("");
|
||||
const {
|
||||
sites,
|
||||
currentPage,
|
||||
itemPerPage,
|
||||
total,
|
||||
search,
|
||||
setSearch,
|
||||
handlePageChange,
|
||||
setItemPerPage,
|
||||
loadSites
|
||||
} = useSites();
|
||||
|
||||
const handlePageChange = (page: number) => {
|
||||
setCurrentPage(page);
|
||||
};
|
||||
|
||||
const loadSites = useCallback(() => {
|
||||
axios.get('/api/sites/get_all', {
|
||||
params: {
|
||||
currentPage,
|
||||
itemPerPage,
|
||||
search,
|
||||
},
|
||||
}).then((response) => {
|
||||
setSites(response.data.sites);
|
||||
setTotal(response.data.total);
|
||||
});
|
||||
}, [currentPage, itemPerPage, search]);
|
||||
|
||||
useEffect(() => {
|
||||
loadSites();
|
||||
}, [loadSites]);
|
||||
|
||||
useEffect(() => {
|
||||
const itemPerPage = Cookies.get('sites-itemPerPage');
|
||||
if (itemPerPage) {
|
||||
setItemPerPage(Number(itemPerPage));
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Sidebar
|
||||
username={username}
|
||||
@ -58,30 +35,41 @@ export default function SitesPage({ username, name }: SitesPageProps) {
|
||||
<div className="flex gap-4 items-center">
|
||||
<div className="flex-1">
|
||||
<h1 className="text-2xl font-bold">Sites</h1>
|
||||
<p className="text-sm opacity-70">Manage your sites. Sites are real-world locations where you can monitor your assets & add networks.</p>
|
||||
<p className="text-sm opacity-70">
|
||||
Manage your sites. Sites are real-world locations where you can
|
||||
monitor your assets & add networks.
|
||||
</p>
|
||||
</div>
|
||||
<button className="btn btn-primary" onClick={() => document.getElementById('add_site')?.showModal()}>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => document.getElementById('add_site')?.showModal()}
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
Add Site
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AddSite onSiteAdded={loadSites} />
|
||||
<SearchAndLayout
|
||||
search={search}
|
||||
setSearch={setSearch}
|
||||
itemPerPage={itemPerPage}
|
||||
setItemPerPage={setItemPerPage}
|
||||
/>
|
||||
|
||||
<div className="flex gap-2 items-center pt-4">
|
||||
<input type="text" placeholder="Search..." className="input input-bordered w-full" onChange={(e) => setSearch(e.target.value)} />
|
||||
<select defaultValue="Pick a font" className="select w-24" value={itemPerPage} onChange={(e) => {
|
||||
setItemPerPage(Number(e.target.value));
|
||||
Cookies.set('sites-itemPerPage', e.target.value);
|
||||
}}>
|
||||
<option disabled={true}>Layout</option>
|
||||
<option value={5}>List</option>
|
||||
<option value={10}>Grid</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className={itemPerPage === 5 ? "flex flex-col gap-4 pt-4" : "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4"}>
|
||||
<div className={
|
||||
itemPerPage === 5
|
||||
? "flex flex-col gap-4 pt-4"
|
||||
: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4"
|
||||
}>
|
||||
{sites.map((site: any) => (
|
||||
<Sites key={site.id} id={site.id} name={site.name} description={site.description} networks={site.networks} />
|
||||
<Sites
|
||||
key={site.id}
|
||||
id={site.id}
|
||||
name={site.name}
|
||||
description={site.description}
|
||||
networks={site.networks}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
||||
38
components/SearchAndLayout.tsx
Normal file
38
components/SearchAndLayout.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { ChangeEvent } from "react";
|
||||
|
||||
interface SearchAndLayoutProps {
|
||||
search: string;
|
||||
setSearch: (value: string) => void;
|
||||
itemPerPage: number;
|
||||
setItemPerPage: (value: number) => void;
|
||||
}
|
||||
|
||||
const SearchAndLayout = ({
|
||||
search,
|
||||
setSearch,
|
||||
itemPerPage,
|
||||
setItemPerPage
|
||||
}: SearchAndLayoutProps) => (
|
||||
<div className="flex gap-2 items-center pt-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
className="input input-bordered w-full"
|
||||
value={search}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => setSearch(e.target.value)}
|
||||
/>
|
||||
<select
|
||||
className="select w-24"
|
||||
value={itemPerPage}
|
||||
onChange={(e: ChangeEvent<HTMLSelectElement>) =>
|
||||
setItemPerPage(Number(e.target.value))
|
||||
}
|
||||
>
|
||||
<option disabled>Layout</option>
|
||||
<option value={5}>List</option>
|
||||
<option value={10}>Grid</option>
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default SearchAndLayout;
|
||||
49
hooks/useSites.ts
Normal file
49
hooks/useSites.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const useSites = () => {
|
||||
const [sites, setSites] = useState([]);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemPerPage, setItemPerPage] = useState(5);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const loadSites = useCallback(() => {
|
||||
axios.get('/api/sites/get_all', {
|
||||
params: { currentPage, itemPerPage, search }
|
||||
}).then((response) => {
|
||||
setSites(response.data.sites);
|
||||
setTotal(response.data.total);
|
||||
});
|
||||
}, [currentPage, itemPerPage, search]);
|
||||
|
||||
useEffect(() => {
|
||||
loadSites();
|
||||
}, [loadSites]);
|
||||
|
||||
useEffect(() => {
|
||||
const savedItemPerPage = Cookies.get('sites-itemPerPage');
|
||||
if (savedItemPerPage) setItemPerPage(Number(savedItemPerPage));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
Cookies.set('sites-itemPerPage', itemPerPage.toString());
|
||||
}, [itemPerPage]);
|
||||
|
||||
const handlePageChange = (page: number) => setCurrentPage(page);
|
||||
|
||||
return {
|
||||
sites,
|
||||
currentPage,
|
||||
itemPerPage,
|
||||
total,
|
||||
search,
|
||||
setSearch,
|
||||
handlePageChange,
|
||||
setItemPerPage,
|
||||
loadSites
|
||||
};
|
||||
};
|
||||
|
||||
export default useSites;
|
||||
Loading…
x
Reference in New Issue
Block a user