feat(frontend): add new search card components and update styling

- Introduced new search card components for Contact, Event, Location, Note, Receipt, and Website.
- Updated the App component to utilize these new components for displaying search results.
- Changed the default font from Manrope to Switzer and updated related styles.
- Added a new dependency `solid-motionone` to package.json.
- Improved search functionality with a new sample data structure and enhanced search logic.
This commit is contained in:
2025-03-23 21:56:09 +01:00
parent 4c85f1de79
commit caf168c7a1
18 changed files with 791 additions and 205 deletions

View File

@@ -0,0 +1,26 @@
import { Separator } from "@kobalte/core/separator";
import { IconUser } from "@tabler/icons-solidjs";
import type { Contact } from "../../network/types";
type Props = {
item: Contact;
};
export const SearchCardContact = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-orange-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">{data.name}</p>
<IconUser size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">{data.phoneNumber}</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.notes}
</p>
</div>
);
};

View File

@@ -0,0 +1,33 @@
import { Separator } from "@kobalte/core/separator";
import { IconCalendar } from "@tabler/icons-solidjs";
import type { Event } from "../../network/types";
type Props = {
item: Event;
};
export const SearchCardEvent = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-purple-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">{data.title}</p>
<IconCalendar size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">
Organized by {data.organizer.name} on{" "}
{new Date(data.dateTime.start).toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
})}
</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.description}
</p>
</div>
);
};

View File

@@ -0,0 +1,26 @@
import { Separator } from "@kobalte/core/separator";
import { IconMapPin } from "@tabler/icons-solidjs";
import type { Location } from "../../network/types";
type Props = {
item: Location;
};
export const SearchCardLocation = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-red-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">{data.name}</p>
<IconMapPin size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">{data.address}</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.description}
</p>
</div>
);
};

View File

@@ -0,0 +1,26 @@
import { Separator } from "@kobalte/core/separator";
import { IconNote } from "@tabler/icons-solidjs";
import type { Note } from "../../network/types";
type Props = {
item: Note;
};
export const SearchCardNote = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-green-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">{data.title}</p>
<IconNote size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">{data.keywords}</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.content}
</p>
</div>
);
};

View File

@@ -0,0 +1,30 @@
import { Separator } from "@kobalte/core/separator";
import { IconReceipt } from "@tabler/icons-solidjs";
import type { Receipt } from "../../network/types";
type Props = {
item: Receipt;
};
export const SearchCardReceipt = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-yellow-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">
{data.orderNumber} - {data.vendor}
</p>
<IconReceipt size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">
{data.shippingAddress.address}
</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.amount} {data.currency}
</p>
</div>
);
};

View File

@@ -0,0 +1,26 @@
import { Separator } from "@kobalte/core/separator";
import { IconLink } from "@tabler/icons-solidjs";
import type { Website } from "../../network/types";
type Props = {
item: Website;
};
export const SearchCardWebsite = ({ item }: Props) => {
const { data } = item;
return (
<div class="absolute inset-0 p-3 bg-blue-50">
<div class="grid grid-cols-[auto_20px] gap-1 mb-1">
<p class="text-sm text-neutral-900 font-bold">{data.title}</p>
<IconLink size={20} class="text-neutral-500 mt-1" />
</div>
<p class="text-xs text-neutral-500">{data.url}</p>
<Separator class="my-2" />
<p class="text-xs text-neutral-500 line-clamp-2 overflow-hidden">
{data.description}
</p>
</div>
);
};