mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-02-23 15:34:21 +01:00
feat: add cover image, make categories icons dynamic
This commit is contained in:
BIN
public/assets/images/cover.png
Normal file
BIN
public/assets/images/cover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
@@ -63,5 +63,9 @@
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
<script
|
||||
src="https://kit.fontawesome.com/db42690d87.js"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -48,8 +48,8 @@ export default function Categories(props: Props) {
|
||||
|
||||
const sortedByAppsCount = [...data.categoryList!].filter(v => !!v?.projectsCount).sort((a, b) => Number(b?.projectsCount!) - Number(a?.projectsCount!))
|
||||
|
||||
return (
|
||||
|
||||
return (
|
||||
<div className="relative group">
|
||||
<div className="overflow-hidden border-b border-gray-200" ref={viewportRef}>
|
||||
<div className="select-none w-full flex gap-8">
|
||||
@@ -58,22 +58,26 @@ export default function Categories(props: Props) {
|
||||
props.onChange?.(null)
|
||||
}}
|
||||
className={`
|
||||
flex flex-col font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-16 py-16 min-w-max
|
||||
text-center flex flex-wrap gap-8 flex-col justify-end font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-16 py-16 min-w-max
|
||||
${props.value === null ? "text-primary-500 border-b-2 border-primary-500" : "text-gray-500"}
|
||||
`}
|
||||
>{props.filtersActive ? "Search results" : "All projects"}</button>
|
||||
{sortedByAppsCount.map((category, idx) =>
|
||||
<button
|
||||
{sortedByAppsCount.map((category, idx) => {
|
||||
if (category?.icon)
|
||||
console.log(category?.icon);
|
||||
|
||||
return <button
|
||||
key={category!.id}
|
||||
onClick={() => {
|
||||
const isSame = props.value?.id === category?.id;
|
||||
props.onChange?.(isSame ? null : category)
|
||||
}}
|
||||
className={`
|
||||
flex flex-col font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-8 py-16 min-w-max
|
||||
text-center flex flex-wrap gap-8 flex-col justify-end items-center font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-8 py-16 min-w-max
|
||||
${props.value?.id === category?.id ? "text-primary-500 border-b-2 border-primary-500" : "text-gray-500"}
|
||||
`}
|
||||
>{category!.name} ({category?.projectsCount!})</button>
|
||||
><i className={category?.icon ? `fa-regular fa-${category.icon}` : "fa-regular fa-circle-question"}></i> <span className='w-full'>{category!.name} ({category?.projectsCount!})</span></button>
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,7 +40,6 @@ export default function ExplorePage() {
|
||||
|
||||
useUpdateUrlWithFilters(filters)
|
||||
|
||||
// useQueryState(removeEmptyFitlers(filters ?? {}));
|
||||
|
||||
const { queryFilters, hasSearchFilters } = useMemo(() => {
|
||||
let filter: QueryFilter = {}
|
||||
@@ -88,7 +87,7 @@ export default function ExplorePage() {
|
||||
notifyOnNetworkStatusChange: true,
|
||||
onCompleted: data => {
|
||||
if ((data.projects?.length ?? 0) < PAGE_SIZE) setCanFetchMore(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -156,10 +155,10 @@ export default function ExplorePage() {
|
||||
<title>{`Lightning Landscape`}</title>
|
||||
<meta property="og:title" content={`Lightning Landscape`} />
|
||||
</Helmet>
|
||||
<div className='page-container'>
|
||||
<Header
|
||||
category={selectedCategory}
|
||||
/>
|
||||
<Header
|
||||
category={selectedCategory}
|
||||
/>
|
||||
<div className="content-container mt-16">
|
||||
<div className="grid grid-cols-1 md:grid-cols-[1fr_auto] items-center gap-x-32 gap-y-16">
|
||||
<div className="min-w-0 max-md:row-start-2"><Categories filtersActive={hasSearchFilters} value={selectedCategory} onChange={v => selectCategoryTab(v)} /></div>
|
||||
<Button
|
||||
@@ -171,16 +170,16 @@ export default function ExplorePage() {
|
||||
<span className='align-middle'>Filters</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mt-40">
|
||||
<ProjectsGrid
|
||||
isLoading={isLoading}
|
||||
isLoadingMore={isLoadingMore}
|
||||
projects={data?.projects?.filter((p) => p !== null) as any[] ?? []}
|
||||
/>
|
||||
{canLoadMore && <div className="flex justify-center mt-36">
|
||||
<Button onClick={clickFetchMore} color="gray"><HiOutlineChevronDoubleDown /> Load more</Button>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-40 page-container">
|
||||
<ProjectsGrid
|
||||
isLoading={isLoading}
|
||||
isLoadingMore={isLoadingMore}
|
||||
projects={data?.projects?.filter((p) => p !== null) as any[] ?? []}
|
||||
/>
|
||||
{canLoadMore && <div className="flex justify-center mt-36">
|
||||
<Button onClick={clickFetchMore} color="gray"><HiOutlineChevronDoubleDown /> Load more</Button>
|
||||
</div>}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -20,8 +20,8 @@ export default function Header(props: Props) {
|
||||
|
||||
return (
|
||||
<div className='h-[280px] rounded-20 overflow-hidden relative flex flex-col justify-center items-center gap-8'>
|
||||
{/* <img src={img.startsWith('https://via.placeholder.com/') ? DEFAULT_IMG : img} alt="" className='absolute inset-0 w-full h-full object-cover z-[-1]' /> */}
|
||||
{/* <div className='absolute inset-0 w-full h-full bg-black bg-opacity-50 z-[-1]' /> */}
|
||||
<img src="/assets/images/cover.png" alt="" className='absolute inset-0 opacity-20 w-full h-full object-cover z-[-1]' />
|
||||
{/* <div className='absolute inset-0 w-full h-full bg-gray-300 bg-opacity-50 z-[-1]' /> */}
|
||||
{/* <Link
|
||||
to={PAGES_ROUTES.projects.default}
|
||||
className="
|
||||
|
||||
Reference in New Issue
Block a user