-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from kawalcovid19/feature/search
Merge pull request #75 from kawalcovid19/feature/database-page
- Loading branch information
Showing
10 changed files
with
182 additions
and
79 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
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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import Link from "next/link"; | ||
|
||
export type ProvinceListItem = { | ||
initials: string; | ||
name: string; | ||
slug: string; | ||
count: number; | ||
}; | ||
|
||
type ProvinceListProps = { | ||
data: ProvinceListItem[]; | ||
}; | ||
|
||
export function ProvinceList(props: ProvinceListProps) { | ||
return ( | ||
<ul className="mt-3 grid grid-cols-1 gap-5 sm:gap-6 sm:grid-cols-2 lg:grid-cols-3"> | ||
{props.data.map((province) => ( | ||
<li | ||
key={province.name} | ||
className="col-span-1 flex shadow-sm rounded-md" | ||
> | ||
<div className="bg-blue-500 flex-shrink-0 flex items-center justify-center w-16 text-white text-sm font-medium rounded-l-md"> | ||
{province.initials} | ||
</div> | ||
<Link href={`/provinces/${province.slug}`}> | ||
<a className="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-md truncate"> | ||
<div className="flex-1 px-4 py-2 text-sm truncate"> | ||
<span className="text-gray-900 font-medium hover:text-gray-600"> | ||
{province.name} | ||
</span> | ||
<p className="text-gray-500">{province.count} Entri</p> | ||
</div> | ||
</a> | ||
</Link> | ||
</li> | ||
))} | ||
</ul> | ||
); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
interface FormElements extends HTMLFormControlsCollection { | ||
keywordsInput: HTMLInputElement; | ||
} | ||
|
||
interface UsernameFormElement extends HTMLFormElement { | ||
readonly elements: FormElements; | ||
} | ||
|
||
export function SearchForm({ | ||
itemName, | ||
onSubmitKeywords, | ||
}: { | ||
itemName: string; | ||
onSubmitKeywords: (keywords: string) => void; | ||
}) { | ||
function handleSubmit(event: React.FormEvent<UsernameFormElement>) { | ||
event.preventDefault(); | ||
onSubmitKeywords(event.currentTarget.elements.keywordsInput.value); | ||
} | ||
|
||
return ( | ||
<form className="flex items-center" onSubmit={handleSubmit}> | ||
<label htmlFor="keywordsInput" className="flex-shrink-0"> | ||
Cari {itemName}: | ||
</label> | ||
<input | ||
id="keywordsInput" | ||
type="text" | ||
className="focus:ring-indigo-500 focus:border-indigo-500 block w-full px-2 py-2 sm:text-sm border-gray-300 border-2 rounded-md my-5 mx-2" | ||
/> | ||
<button | ||
type="submit" | ||
className="bg-blue-600 text-white ml-2 py-2 px-6 rounded" | ||
> | ||
Cari | ||
</button> | ||
</form> | ||
); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { useState } from "react"; | ||
|
||
export function useSearch<T = unknown[]>(items: T[], fieldNames: string[]) { | ||
const [filteredItems, setFilteredItems] = useState<T[]>(items); | ||
const handleSubmitKeywords = (keywords: string) => { | ||
const lowerKeywords = keywords.toLowerCase(); | ||
setFilteredItems( | ||
items.filter((item) => { | ||
const filterBy = (fieldName: keyof T) => { | ||
const selectedField = item[fieldName]; | ||
|
||
if (typeof selectedField === "string") { | ||
return selectedField.toLowerCase().includes(lowerKeywords); | ||
} else { | ||
return false; | ||
} | ||
}; | ||
|
||
const filterFunctions = fieldNames.map((fieldName) => | ||
filterBy(fieldName as keyof T) | ||
); | ||
return filterFunctions.reduce((acc, curr) => acc || curr, false); | ||
}) | ||
); | ||
}; | ||
return [filteredItems, handleSubmitKeywords] as const; | ||
} |
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 was deleted.
Oops, something went wrong.
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
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 |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { GetStaticProps } from "next"; | ||
import provinces from "../../lib/provinces"; | ||
import { getInitial, getSlug } from "../../lib/string-utils"; | ||
import { SearchForm } from "../../components/search-form"; | ||
import { ProvinceList, ProvinceListItem } from "../../components/province-list"; | ||
import { useSearch } from "../../lib/hooks/use-search"; | ||
|
||
type ProvincesPageProps = { | ||
provincesList: ProvinceListItem[]; | ||
}; | ||
|
||
export default function ProvincesPage(props: ProvincesPageProps) { | ||
const [filteredProvinces, handleSubmitKeywords] = useSearch( | ||
props.provincesList, | ||
["name"] | ||
); | ||
return ( | ||
<div> | ||
<h2 className="text-gray-500 text-xs font-medium uppercase tracking-wide"> | ||
Daftar Provinsi | ||
</h2> | ||
<SearchForm itemName="provinsi" onSubmitKeywords={handleSubmitKeywords} /> | ||
<ProvinceList data={filteredProvinces} /> | ||
</div> | ||
); | ||
} | ||
|
||
export const getStaticProps: GetStaticProps = () => { | ||
const provincesList = provinces.map(({ name, data }, index) => ({ | ||
initials: getInitial(name), | ||
name, | ||
slug: getSlug(name, index), | ||
count: data.length, | ||
})); | ||
provincesList.shift(); | ||
return { | ||
props: { | ||
provincesList, | ||
}, | ||
}; | ||
}; |