refactor: property show site list
This commit is contained in:
parent
0aadf6f6f7
commit
7251656bef
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,3 +10,10 @@ export type SelectOptions = {
|
|||
value: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type SiteList = {
|
||||
[domain: string]: {
|
||||
name: string;
|
||||
pubkey: string;
|
||||
};
|
||||
};
|
||||
|
|
32
app/utils.ts
32
app/utils.ts
|
@ -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 = [
|
||||
|
|
12
bridge.mts
12
bridge.mts
|
@ -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({
|
||||
|
|
Loading…
Reference in New Issue