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

View File

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

View File

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

7
app/types.d.ts vendored
View File

@ -10,3 +10,10 @@ export type SelectOptions = {
value: 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 { clsx, type ClassValue } from "clsx";
import { type ClassValue, clsx } from "clsx";
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[]) {
return twMerge(clsx(inputs));
@ -45,30 +46,9 @@ export async function getResults({
}
export function getAvailableSites() {
const statuses: SelectOptions[] = [
{
value: "backlog",
label: "Backlog",
},
{
value: "todo",
label: "Todo",
},
{
value: "in progress",
label: "In Progress",
},
{
value: "done",
label: "Done",
},
{
value: "canceled",
label: "Canceled",
},
];
return statuses;
return JSON.parse(
fs.readFileSync("sites.json", { encoding: "utf8" })
) as SiteList;
}
export const FILTER_TIMES = [

View File

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