refactor: property show site list

This commit is contained in:
Derrick Hammer 2023-12-22 04:11:03 -05:00
parent 0aadf6f6f7
commit 7251656bef
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
6 changed files with 43 additions and 51 deletions

View File

@ -25,10 +25,11 @@ import {
SelectValue, SelectValue,
} from "./ui/select"; } from "./ui/select";
import { SitesCombobox } from "./SitesCombobox"; import { SitesCombobox } from "./SitesCombobox";
import { SearchResult, SiteList } from "@/types.js";
type Props = {}; type Props = {};
const SearchBar = () => { const SearchBar = ({ sites }: { sites: SiteList }) => {
let navigate = useNavigate(); let navigate = useNavigate();
let { pathname } = useLocation(); let { pathname } = useLocation();
let [searchParams] = useSearchParams(); let [searchParams] = useSearchParams();
@ -149,7 +150,7 @@ const SearchBar = () => {
) : ( ) : (
<div className="justify-self-end min-w-[220px] flex justify-end gap-2"> <div className="justify-self-end min-w-[220px] flex justify-end gap-2">
{/* Dropdown component should be here */} {/* Dropdown component should be here */}
<SitesCombobox /> <SitesCombobox siteList={sites} />
{/* Dropdown component should be here */} {/* Dropdown component should be here */}
<Select defaultValue={"0"}> <Select defaultValue={"0"}>
<SelectTrigger className="hover:bg-muted w-auto"> <SelectTrigger className="hover:bg-muted w-auto">

View File

@ -16,13 +16,20 @@ import {
} from "@/components/ui/popover"; } from "@/components/ui/popover";
import { ChevronDownIcon } from "@heroicons/react/24/solid"; import { ChevronDownIcon } from "@heroicons/react/24/solid";
import { getAvailableSites } from "@/utils"; import { getAvailableSites } from "@/utils";
import { SelectOptions } from "@/types.js"; import { SelectOptions, SiteList } from "@/types.js";
import slugify from "slugify";
export function SitesCombobox() { export function SitesCombobox({ siteList }: { siteList: SiteList }) {
const statuses = getAvailableSites(); const sites = Object.entries(siteList).map((item) => {
return {
label: item[1].name,
value: slugify(item[0]),
};
});
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [selectedStatus, setSelectedStatus] = const [selectedSite, setSelectedSite] = React.useState<SelectOptions | null>(
React.useState<SelectOptions | null>(null); null
);
return ( return (
<div className="flex flex- items-center space-x-4"> <div className="flex flex- items-center space-x-4">
@ -32,24 +39,24 @@ export function SitesCombobox() {
variant={"ghost"} variant={"ghost"}
className="max-w-[120px] focus:ring-2 focus:ring-ring px-2 font-bold items-center w-full flex justify-between text-white text-xs uppercase" className="max-w-[120px] focus:ring-2 focus:ring-ring px-2 font-bold items-center w-full flex justify-between text-white text-xs uppercase"
> >
{selectedStatus ? <>{selectedStatus.label}</> : <>All Sites</>} {selectedSite ? <>{selectedSite.label}</> : <>All Sites</>}
<ChevronDownIcon className="ml-3 w-5 h-5" /> <ChevronDownIcon className="ml-3 w-5 h-5" />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="p-0" side="right" align="start"> <PopoverContent className="p-0" side="right" align="start">
<Command> <Command>
<CommandInput placeholder="Change status..." /> <CommandInput placeholder="Select site..." />
<CommandList> <CommandList>
<CommandEmpty>No results found.</CommandEmpty> <CommandEmpty>No results found.</CommandEmpty>
<CommandGroup> <CommandGroup>
{statuses?.map((status) => ( {sites?.map((status) => (
<CommandItem <CommandItem
className="text-white" className="text-white"
key={status.value} key={status.value}
value={status.value} value={status.value}
onSelect={(value) => { onSelect={(value) => {
setSelectedStatus( setSelectedSite(
statuses.find((priority) => priority.value === value) || sites.find((priority) => priority.value === value) ||
null null
); );
setOpen(false); setOpen(false);

View File

@ -8,9 +8,12 @@ import { Article } from "@/lib/prisma";
import Logo from "@/images/lume-logo-bg.png"; import Logo from "@/images/lume-logo-bg.png";
import { json, LoaderFunction, redirect } from "@remix-run/node"; import { json, LoaderFunction, redirect } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react"; import { useLoaderData } from "@remix-run/react";
import type { SiteList } from "@/types.js";
import { getAvailableSites } from "@/utils";
type LoaderData = { type LoaderData = {
data: ApiResponse<Article>; data: ApiResponse<Article>;
sites: SiteList;
}; };
export let loader: LoaderFunction = async ({ request }) => { export let loader: LoaderFunction = async ({ request }) => {
@ -26,15 +29,17 @@ export let loader: LoaderFunction = async ({ request }) => {
// Fetch your data here // Fetch your data here
const data = await fetchFeedData({}); const data = await fetchFeedData({});
const sites = getAvailableSites();
// Return the fetched data as JSON // Return the fetched data as JSON
return json({ data }); return json({ data, sites });
}; };
export default function Index() { export default function Index() {
let { data } = useLoaderData<LoaderData>(); let { data, sites } = useLoaderData<LoaderData>();
return ( return (
<> <>
<SearchBar /> <SearchBar sites={sites} />
<div className="space-y-8 w-full my-10"> <div className="space-y-8 w-full my-10">
<div className="flex flex-row flex-wrap justify-between w-full"> <div className="flex flex-row flex-wrap justify-between w-full">
<Feed <Feed

7
app/types.d.ts vendored
View File

@ -10,3 +10,10 @@ export type SelectOptions = {
value: string; value: string;
label: string; label: string;
}; };
export type SiteList = {
[domain: string]: {
name: string;
pubkey: string;
};
};

View File

@ -1,7 +1,8 @@
import { formatDistanceToNow, subDays, subMonths, subYears } from "date-fns"; import { formatDistanceToNow, subDays, subMonths, subYears } from "date-fns";
import { clsx, type ClassValue } from "clsx"; import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { SearchResult, SelectOptions } from "@/types.js"; import { SearchResult, SiteList } from "@/types.js";
import fs from "fs";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs));
@ -45,30 +46,9 @@ export async function getResults({
} }
export function getAvailableSites() { export function getAvailableSites() {
const statuses: SelectOptions[] = [ return JSON.parse(
{ fs.readFileSync("sites.json", { encoding: "utf8" })
value: "backlog", ) as SiteList;
label: "Backlog",
},
{
value: "todo",
label: "Todo",
},
{
value: "in progress",
label: "In Progress",
},
{
value: "done",
label: "Done",
},
{
value: "canceled",
label: "Canceled",
},
];
return statuses;
} }
export const FILTER_TIMES = [ export const FILTER_TIMES = [

View File

@ -1,17 +1,9 @@
import * as fs from "fs";
import { S5Client } from "@lumeweb/s5-js"; import { S5Client } from "@lumeweb/s5-js";
import { CID } from "@lumeweb/libs5"; import { CID } from "@lumeweb/libs5";
import axios from "axios"; import axios from "axios";
import { getAvailableSites } from "app/utils.js";
type SiteList = { const sites = getAvailableSites();
[domain: string]: {
pubkey: string;
};
};
const sites = JSON.parse(
fs.readFileSync("sites.json", { encoding: "utf8" }),
) as SiteList;
const client = new S5Client("https://s5.web3portal.com"); const client = new S5Client("https://s5.web3portal.com");
const httpClient = axios.create({ const httpClient = axios.create({