-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(frontend): implement resources listing pages
- Loading branch information
1 parent
3e8b66b
commit b50335d
Showing
4 changed files
with
273 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,94 @@ | ||
import React, { useState } from "react"; | ||
import { useLocation } from 'react-router-dom'; | ||
import { useLocation } from "react-router-dom"; | ||
|
||
export const Navbar: React.FC = () => { | ||
const location = useLocation(); | ||
|
||
const location = useLocation(); | ||
const [nav, setNav] = useState(false); | ||
|
||
const [nav, setNav] = useState(false); | ||
const handleNav = () => { | ||
setNav(!nav); | ||
}; | ||
|
||
const handleNav = () => { | ||
setNav(!nav); | ||
}; | ||
const verifyCurrentRouteAndApplyStylingClasses = (path: string) => { | ||
if (location.pathname === path) { | ||
return "bg-gray-900 text-white rounded-md px-3 py-2 text-sm font-medium"; | ||
} | ||
|
||
const verifyCurrentRouteAndApplyStylingClasses = (path: string) => { | ||
console.log(location.pathname) | ||
if (location.pathname === path) { | ||
return "bg-gray-900 text-white rounded-md px-3 py-2 text-sm font-medium" | ||
} | ||
return "text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium"; | ||
}; | ||
|
||
return "text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium" | ||
} | ||
return ( | ||
<nav className="bg-gray-800"> | ||
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8"> | ||
<div className="relative flex h-16 items-center justify-between"> | ||
<div className="absolute inset-y-0 left-0 flex items-center sm:hidden"> | ||
<button | ||
onClick={handleNav} | ||
type="button" | ||
className="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" | ||
aria-controls="mobile-menu" | ||
aria-expanded="false" | ||
> | ||
<span className="absolute -inset-0.5"></span> | ||
<span className="sr-only">Open main menu</span> | ||
|
||
<svg | ||
className="block h-6 w-6" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
strokeWidth="1.5" | ||
stroke="currentColor" | ||
aria-hidden="true" | ||
> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /> | ||
</svg> | ||
|
||
return ( | ||
<nav className="bg-gray-800"> | ||
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8"> | ||
<div className="relative flex h-16 items-center justify-between"> | ||
<div className="absolute inset-y-0 left-0 flex items-center sm:hidden"> | ||
|
||
<button onClick={handleNav} type="button" className="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" aria-controls="mobile-menu" aria-expanded="false"> | ||
<span className="absolute -inset-0.5"></span> | ||
<span className="sr-only">Open main menu</span> | ||
|
||
<svg className="block h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /> | ||
</svg> | ||
|
||
<svg className="hidden h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true"> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" /> | ||
</svg> | ||
</button> | ||
</div> | ||
<div className="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start"> | ||
<span className="flex flex-shrink-0 items-center text-white">Book's Manager</span> | ||
<div className="hidden sm:ml-6 sm:block"> | ||
<div className="flex space-x-4"> | ||
<a href="/" className={verifyCurrentRouteAndApplyStylingClasses("/")} aria-current="page">Books</a> | ||
<a href="/authors" className={verifyCurrentRouteAndApplyStylingClasses("/authors")}>Authors</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<svg | ||
className="hidden h-6 w-6" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
strokeWidth="1.5" | ||
stroke="currentColor" | ||
aria-hidden="true" | ||
> | ||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" /> | ||
</svg> | ||
</button> | ||
</div> | ||
<div className="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start"> | ||
<span className="flex flex-shrink-0 items-center text-white">Book's Manager</span> | ||
<div className="hidden sm:ml-6 sm:block"> | ||
<div className="flex space-x-4"> | ||
<a href="/" className={verifyCurrentRouteAndApplyStylingClasses("/")} aria-current="page"> | ||
Books | ||
</a> | ||
<a href="/authors" className={verifyCurrentRouteAndApplyStylingClasses("/authors")}> | ||
Authors | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div className={`sm:hidden ${!nav && "hidden"}`} id="mobile-menu"> | ||
<div className="space-y-1 px-2 pb-3 pt-2"> | ||
<a href="/" className="bg-gray-900 text-white block rounded-md px-3 py-2 text-base font-medium" aria-current="page">Books</a> | ||
<a href="/authors" className="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Authors</a> | ||
</div> | ||
</div> | ||
</nav> | ||
) | ||
} | ||
<div className={`sm:hidden ${!nav && "hidden"}`} id="mobile-menu"> | ||
<div className="space-y-1 px-2 pb-3 pt-2"> | ||
<a | ||
href="/" | ||
className="bg-gray-900 text-white block rounded-md px-3 py-2 text-base font-medium" | ||
aria-current="page" | ||
> | ||
Books | ||
</a> | ||
<a | ||
href="/authors" | ||
className="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium" | ||
> | ||
Authors | ||
</a> | ||
</div> | ||
</div> | ||
</nav> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,102 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import ManagementService from 'services/managementService'; | ||
import { useFilterHook } from 'components/Hooks/UseFilterHook'; | ||
import { Author } from 'types/author'; | ||
|
||
const managementService = new ManagementService() | ||
import React, { useEffect, useState } from "react"; | ||
import ManagementService from "services/managementService"; | ||
import { useFilterHook } from "components/Hooks/UseFilterHook"; | ||
import { Author } from "types/author"; | ||
|
||
const managementService = new ManagementService(); | ||
|
||
const Authors: React.FC = () => { | ||
const [authors, setAuthors] = useState<Author[]>([]) | ||
const { handleChangeFilter, shouldFilterInWith } = useFilterHook(); | ||
|
||
useEffect(() => { | ||
loadAuthors() | ||
}, []) | ||
|
||
const loadAuthors = async () => { | ||
const authors = await managementService.getAuthors() | ||
const [authors, setAuthors] = useState<Author[]>([]); | ||
const { handleChangeFilter, shouldFilterInWith } = useFilterHook(); | ||
|
||
setAuthors(authors) | ||
} | ||
useEffect(() => { | ||
loadAuthors(); | ||
}, []); | ||
|
||
const loadAuthors = async () => { | ||
const authors = await managementService.getAuthors(); | ||
|
||
return ( | ||
<> | ||
<div className="flex items-center py-2 justify-between"> | ||
<label htmlFor="table-search" className="sr-only">Search</label> | ||
<div className="relative"> | ||
<div className="absolute inset-y-0 rtl:inset-r-0 start-0 flex items-center ps-3 pointer-events-none"> | ||
<svg className="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20"> | ||
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" /> | ||
</svg> | ||
</div> | ||
<input type="text" id="table-search" onChange={handleChangeFilter} className="block py-3 ps-10 text-sm border rounded-lg w-80 focus:ring-blue-500 focus:border-blue-500 " placeholder="Search for items" /> | ||
</div> | ||
<a href='/authors/create' className="max-sm:w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> | ||
+ Add author | ||
</a> | ||
</div> | ||
<hr /> | ||
<div className='block max-h-[78dvh] overflow-y-auto'> | ||
<table className="w-full text-sm text-left rtl:text-right text-gray-500"> | ||
<thead className="text-xs uppercase "> | ||
<tr> | ||
setAuthors(authors); | ||
}; | ||
|
||
<th scope="col" className="px-1 py-3"> | ||
Author | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
Nationality | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
Birth date | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{authors?.length > 0 && authors.map(({ name, nationality, birthDate, email, id }: Author) => ( | ||
shouldFilterInWith(name, nationality, birthDate, email, id) | ||
&& ( | ||
<tr key={id} className="border-b hover:bg-gray-50"> | ||
<th scope="row" className="px-1 py-4 font-medium text-gray-900 whitespace-nowrap"> | ||
{name} | ||
</th> | ||
<td className="px-1 py-4"> | ||
{nationality} | ||
</td> | ||
<td className="px-1 py-4"> | ||
{birthDate} | ||
</td> | ||
<td className="px-1 py-4"> | ||
{email} | ||
</td> | ||
</tr> | ||
) | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
</> | ||
); | ||
return ( | ||
<> | ||
<div className="flex items-center py-2 justify-between"> | ||
<label htmlFor="table-search" className="sr-only"> | ||
Search | ||
</label> | ||
<div className="relative"> | ||
<div className="absolute inset-y-0 rtl:inset-r-0 start-0 flex items-center ps-3 pointer-events-none"> | ||
<svg | ||
className="w-4 h-4 text-gray-500 dark:text-gray-400" | ||
aria-hidden="true" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 20 20" | ||
> | ||
<path | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth="2" | ||
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" | ||
/> | ||
</svg> | ||
</div> | ||
<input | ||
type="text" | ||
id="table-search" | ||
onChange={handleChangeFilter} | ||
className="block py-3 ps-10 text-sm border rounded-lg w-80 focus:ring-blue-500 focus:border-blue-500 " | ||
placeholder="Search for items" | ||
/> | ||
</div> | ||
<a | ||
href="/authors/create" | ||
className="max-sm:w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" | ||
> | ||
+ Add author | ||
</a> | ||
</div> | ||
<hr /> | ||
<div className="block max-h-[78dvh] overflow-y-auto"> | ||
<table className="w-full text-sm text-left rtl:text-right text-gray-500"> | ||
<thead className="text-xs uppercase "> | ||
<tr> | ||
<th scope="col" className="px-1 py-3"> | ||
Author | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
Nationality | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
Birth date | ||
</th> | ||
<th scope="col" className="px-1 py-3"> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{authors?.length > 0 && | ||
authors.map( | ||
({ name, nationality, birthDate, email, id }: Author) => | ||
shouldFilterInWith(name, nationality, birthDate, email, id) && ( | ||
<tr key={id} className="border-b hover:bg-gray-50"> | ||
<th scope="row" className="px-1 py-4 font-medium text-gray-900 whitespace-nowrap"> | ||
{name} | ||
</th> | ||
<td className="px-1 py-4">{nationality}</td> | ||
<td className="px-1 py-4">{birthDate}</td> | ||
<td className="px-1 py-4">{email}</td> | ||
</tr> | ||
), | ||
)} | ||
</tbody> | ||
</table> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default Authors; |
Oops, something went wrong.