feat(cards): adjusting for backend data types
This commit is contained in:
@ -1,46 +1,57 @@
|
|||||||
import { IconSearch } from "@tabler/icons-solidjs";
|
import { IconSearch } from "@tabler/icons-solidjs";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
import { For, createSignal } from "solid-js";
|
import { For, createEffect, createResource, createSignal } from "solid-js";
|
||||||
import { SearchCardContact } from "./components/search-card/SearchCardContact";
|
import { SearchCardContact } from "./components/search-card/SearchCardContact";
|
||||||
import { SearchCardEvent } from "./components/search-card/SearchCardEvent";
|
import { SearchCardEvent } from "./components/search-card/SearchCardEvent";
|
||||||
import { SearchCardLocation } from "./components/search-card/SearchCardLocation";
|
import { SearchCardLocation } from "./components/search-card/SearchCardLocation";
|
||||||
import { SearchCardNote } from "./components/search-card/SearchCardNote";
|
import { SearchCardNote } from "./components/search-card/SearchCardNote";
|
||||||
import { SearchCardReceipt } from "./components/search-card/SearchCardReceipt";
|
import { SearchCardReceipt } from "./components/search-card/SearchCardReceipt";
|
||||||
import { SearchCardWebsite } from "./components/search-card/SearchCardWebsite";
|
import { SearchCardWebsite } from "./components/search-card/SearchCardWebsite";
|
||||||
import { sampleData } from "./network/sampleData";
|
import { UserImage, getUserImages } from "./network";
|
||||||
import type { DataItem } from "./network/types";
|
import type { DataItem } from "./network/types";
|
||||||
import { getCardSize } from "./utils/getCardSize";
|
import { getCardSize } from "./utils/getCardSize";
|
||||||
|
|
||||||
const getCardComponent = (item: DataItem) => {
|
const getCardComponent = (item: UserImage) => {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case "Location":
|
case "location":
|
||||||
return <SearchCardLocation item={item} />;
|
return <SearchCardLocation item={item} />;
|
||||||
case "Event":
|
case "event":
|
||||||
return <SearchCardEvent item={item} />;
|
return <SearchCardEvent item={item} />;
|
||||||
case "Contact":
|
// case "Contact":
|
||||||
return <SearchCardContact item={item} />;
|
// return <SearchCardContact item={item} />;
|
||||||
case "Website":
|
// case "Website":
|
||||||
return <SearchCardWebsite item={item} />;
|
// return <SearchCardWebsite item={item} />;
|
||||||
case "Note":
|
// case "Note":
|
||||||
return <SearchCardNote item={item} />;
|
// return <SearchCardNote item={item} />;
|
||||||
case "Receipt":
|
// case "Receipt":
|
||||||
return <SearchCardReceipt item={item} />;
|
// return <SearchCardReceipt item={item} />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [searchResults, setSearchResults] = createSignal<DataItem[]>([]);
|
const [searchResults, setSearchResults] = createSignal<UserImage[]>([]);
|
||||||
const [searchQuery, setSearchQuery] = createSignal("");
|
const [searchQuery, setSearchQuery] = createSignal("");
|
||||||
const [selectedItem, setSelectedItem] = createSignal<DataItem | null>(null);
|
const [selectedItem, setSelectedItem] = createSignal<UserImage | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
const fuze = new Fuse<DataItem>(sampleData, {
|
const [data] = createResource(getUserImages);
|
||||||
keys: [{ name: "title", weight: 2 }, "rawData"],
|
|
||||||
|
let fuze = new Fuse<UserImage>(data() ?? [], {
|
||||||
|
keys: [{ name: "title", weight: 2 }, "data"],
|
||||||
threshold: 0.4,
|
threshold: 0.4,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
fuze = new Fuse<UserImage>(data() ?? [], {
|
||||||
|
keys: [{ name: "data.Name", weight: 2 }],
|
||||||
|
threshold: 0.4,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const onInputChange = (event: InputEvent) => {
|
const onInputChange = (event: InputEvent) => {
|
||||||
const query = (event.target as HTMLInputElement).value;
|
const query = (event.target as HTMLInputElement).value;
|
||||||
setSearchQuery(query);
|
setSearchQuery(query);
|
||||||
@ -98,7 +109,7 @@ function App() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span class="sr-only">
|
<span class="sr-only">
|
||||||
{item.title}
|
{item.data.Name}
|
||||||
</span>
|
</span>
|
||||||
{getCardComponent(item)}
|
{getCardComponent(item)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Separator } from "@kobalte/core/separator";
|
import { Separator } from "@kobalte/core/separator";
|
||||||
|
|
||||||
import { IconCalendar } from "@tabler/icons-solidjs";
|
import { IconCalendar } from "@tabler/icons-solidjs";
|
||||||
import type { Event } from "../../network/types";
|
import type { UserImage } from "../../network";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
item: Event;
|
item: Extract<UserImage, { type: "event" }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SearchCardEvent = ({ item }: Props) => {
|
export const SearchCardEvent = ({ item }: Props) => {
|
||||||
@ -13,12 +13,12 @@ export const SearchCardEvent = ({ item }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div class="absolute inset-0 p-3 bg-purple-50">
|
<div class="absolute inset-0 p-3 bg-purple-50">
|
||||||
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
|
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
|
||||||
<p class="text-sm text-neutral-900 font-bold">{data.title}</p>
|
<p class="text-sm text-neutral-900 font-bold">{data.Name}</p>
|
||||||
<IconCalendar size={20} class="text-neutral-500 mt-1" />
|
<IconCalendar size={20} class="text-neutral-500 mt-1" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-neutral-500">
|
<p class="text-xs text-neutral-500">
|
||||||
Organized by {data.organizer.name} on{" "}
|
Organized by TODO on{" "}
|
||||||
{new Date(data.dateTime.start).toLocaleDateString("en-US", {
|
{new Date(data.StartDateTime).toLocaleDateString("en-US", {
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
@ -26,7 +26,7 @@ export const SearchCardEvent = ({ item }: Props) => {
|
|||||||
</p>
|
</p>
|
||||||
<Separator class="my-2" />
|
<Separator class="my-2" />
|
||||||
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
|
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
|
||||||
{data.description}
|
{data.Description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Separator } from "@kobalte/core/separator";
|
import { Separator } from "@kobalte/core/separator";
|
||||||
|
|
||||||
import { IconMapPin } from "@tabler/icons-solidjs";
|
import { IconMapPin } from "@tabler/icons-solidjs";
|
||||||
import type { Location } from "../../network/types";
|
import type { UserImage } from "../../network";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
item: Location;
|
item: Extract<UserImage, { type: "location" }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SearchCardLocation = ({ item }: Props) => {
|
export const SearchCardLocation = ({ item }: Props) => {
|
||||||
@ -13,13 +13,13 @@ export const SearchCardLocation = ({ item }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div class="absolute inset-0 p-3 bg-red-50">
|
<div class="absolute inset-0 p-3 bg-red-50">
|
||||||
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
|
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
|
||||||
<p class="text-sm text-neutral-900 font-bold">{data.name}</p>
|
<p class="text-sm text-neutral-900 font-bold">{data.Name}</p>
|
||||||
<IconMapPin size={20} class="text-neutral-500 mt-1" />
|
<IconMapPin size={20} class="text-neutral-500 mt-1" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-neutral-500">{data.address}</p>
|
<p class="text-xs text-neutral-500">{data.Address}</p>
|
||||||
<Separator class="my-2" />
|
<Separator class="my-2" />
|
||||||
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
|
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
|
||||||
{data.description}
|
{data.Description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -82,9 +82,9 @@ const eventDataType = object({
|
|||||||
const dataTypeValidator = variant("type", [locationDataType, eventDataType]);
|
const dataTypeValidator = variant("type", [locationDataType, eventDataType]);
|
||||||
const getUserImagesResponseValidator = array(dataTypeValidator);
|
const getUserImagesResponseValidator = array(dataTypeValidator);
|
||||||
|
|
||||||
export const getUserImages = async (): Promise<
|
export type UserImage = InferOutput<typeof dataTypeValidator>;
|
||||||
InferOutput<typeof getUserImagesResponseValidator>
|
|
||||||
> => {
|
export const getUserImages = async (): Promise<UserImage[]> => {
|
||||||
const request = getBaseRequest({ path: "image" });
|
const request = getBaseRequest({ path: "image" });
|
||||||
|
|
||||||
const res = await fetch(request).then((res) => res.json());
|
const res = await fetch(request).then((res) => res.json());
|
||||||
|
Reference in New Issue
Block a user