import { keepPreviousData } from '@tanstack/react-query' import { useDebounce } from '@uidotdev/usehooks' import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { Grid, List, Loader2, Plus, Search, X } from 'lucide-react' import Link from 'next/link' import { parseAsArrayOf, parseAsString, parseAsStringLiteral, useQueryState } from 'nuqs' import { useEffect } from 'react' import { Button, ToggleGroup, ToggleGroupItem } from 'ui' import { Input } from 'ui-patterns/DataInputs/Input' import { FilterPopover } from '../ui/FilterPopover' import { SortDropdown } from '../ui/SortDropdown' import { PROJECT_LIST_SORT_VALUES, type ProjectListSort, } from '@/components/interfaces/Home/ProjectList/ProjectListSort.utils' import { useOrgProjectsInfiniteQuery } from '@/data/projects/org-projects-infinite-query' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage' import { PROJECT_STATUS } from '@/lib/constants' interface HomePageActionsProps { slug?: string hideNewProject?: boolean } export const HomePageActions = ({ slug: _slug, hideNewProject = false }: HomePageActionsProps) => { const { slug: urlSlug } = useParams() const projectCreationEnabled = useIsFeatureEnabled('projects:create') const slug = _slug ?? urlSlug const [search, setSearch] = useQueryState('search', parseAsString.withDefault('')) const debouncedSearch = useDebounce(search, 500) const [filterStatus, setFilterStatus] = useQueryState( 'status', parseAsArrayOf(parseAsString, ',').withDefault([]) ) const [sort, setSort] = useQueryState( 'sort', parseAsStringLiteral(PROJECT_LIST_SORT_VALUES).withDefault('name_asc') ) const [viewMode, setViewMode] = useLocalStorageQuery(LOCAL_STORAGE_KEYS.PROJECTS_VIEW, 'grid') const [filterStatusStorage, setFilterStatusStorage, { isSuccess: isSuccessFilterStatusStorage }] = useLocalStorageQuery(LOCAL_STORAGE_KEYS.PROJECTS_FILTER, []) const [sortStorage, setSortStorage, { isSuccess: isSuccessSortStorage }] = useLocalStorageQuery(LOCAL_STORAGE_KEYS.PROJECTS_SORT, 'name_asc') const { isFetching: isFetchingProjects } = useOrgProjectsInfiniteQuery( { slug, sort, search: search.length === 0 ? search : debouncedSearch, statuses: filterStatus, }, { placeholderData: keepPreviousData } ) useEffect(() => { if (isSuccessFilterStatusStorage && !!slug) setFilterStatus(filterStatusStorage) }, [filterStatusStorage, isSuccessFilterStatusStorage, setFilterStatus, slug]) useEffect(() => { if (isSuccessSortStorage && slug) setSort(sortStorage) }, [sortStorage, isSuccessSortStorage, setSort, slug]) return (
} size="tiny" className="w-full sm:w-32 md:w-64" value={search} onChange={(event) => setSearch(event.target.value)} actions={[ search && (
{viewMode && setViewMode && ( value && setViewMode(value as 'grid' | 'table')} > )} {projectCreationEnabled && !hideNewProject && ( )}
) }