fix: frontend with new backend schema
This commit is contained in:
@ -34,8 +34,8 @@ type ImageHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ImagesReturn struct {
|
type ImagesReturn struct {
|
||||||
UserImages []models.UserImageWithImage `json:"userImages"`
|
UserImages []models.UserImageWithImage
|
||||||
Lists []models.ListsWithImages `json:"lists"`
|
Stacks []models.ListsWithImages
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ImageHandler) serveImage(w http.ResponseWriter, r *http.Request) {
|
func (h *ImageHandler) serveImage(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -89,7 +89,7 @@ func (h *ImageHandler) listImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
listsWithImages, err := h.userModel.ListWithImages(r.Context(), userId)
|
stacksWithImages, err := h.userModel.ListWithImages(r.Context(), userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
middleware.WriteErrorInternal(h.logger, "could not get lists with images", w)
|
middleware.WriteErrorInternal(h.logger, "could not get lists with images", w)
|
||||||
return
|
return
|
||||||
@ -97,7 +97,7 @@ func (h *ImageHandler) listImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
imagesReturn := ImagesReturn{
|
imagesReturn := ImagesReturn{
|
||||||
UserImages: images,
|
UserImages: images,
|
||||||
Lists: listsWithImages,
|
Stacks: stacksWithImages,
|
||||||
}
|
}
|
||||||
|
|
||||||
middleware.WriteJsonOrError(h.logger, imagesReturn, w)
|
middleware.WriteJsonOrError(h.logger, imagesReturn, w)
|
||||||
|
@ -29,7 +29,7 @@ func (m ImageModel) Save(ctx context.Context, name string, image []byte, userID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m ImageModel) Get(ctx context.Context, imageID uuid.UUID) (model.Image, bool, error) {
|
func (m ImageModel) Get(ctx context.Context, imageID uuid.UUID) (model.Image, bool, error) {
|
||||||
getImageStmt := Image.SELECT(Image.AllColumns.Except(Image.Image)).WHERE(Image.ID.EQ(UUID(imageID)))
|
getImageStmt := Image.SELECT(Image.AllColumns).WHERE(Image.ID.EQ(UUID(imageID)))
|
||||||
|
|
||||||
image := model.Image{}
|
image := model.Image{}
|
||||||
err := getImageStmt.QueryContext(ctx, m.dbPool, &image)
|
err := getImageStmt.QueryContext(ctx, m.dbPool, &image)
|
||||||
|
@ -33,14 +33,14 @@ func (h *StackHandler) getAllStacks(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lists, err := h.stackModel.List(ctx, userID)
|
stacks, err := h.stackModel.List(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Warn("could not get stacks", "err", err)
|
h.logger.Warn("could not get stacks", "err", err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
middleware.WriteJsonOrError(h.logger, lists, w)
|
middleware.WriteJsonOrError(h.logger, stacks, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StackHandler) getStackItems(w http.ResponseWriter, r *http.Request) {
|
func (h *StackHandler) getStackItems(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -17,7 +17,7 @@ const colors = [
|
|||||||
"bg-pink-50",
|
"bg-pink-50",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const ListCard: Component<{ list: List }> = (props) => {
|
export const StackCard: Component<{ list: List }> = (props) => {
|
||||||
return (
|
return (
|
||||||
<A
|
<A
|
||||||
href={`/list/${props.list.ID}`}
|
href={`/list/${props.list.ID}`}
|
||||||
|
@ -34,7 +34,7 @@ export const Notifications = (onCompleteImage: () => void) => {
|
|||||||
ProcessingLists: {},
|
ProcessingLists: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { processingImages } = useSearchImageContext();
|
const { userImages } = useSearchImageContext();
|
||||||
|
|
||||||
const [accessToken] = createResource(getAccessToken);
|
const [accessToken] = createResource(getAccessToken);
|
||||||
|
|
||||||
@ -91,19 +91,19 @@ export const Notifications = (onCompleteImage: () => void) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const images = processingImages();
|
const images = userImages();
|
||||||
if (images == null) {
|
if (images == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upsertImageProcessing(
|
upsertImageProcessing(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
images.map((i) => [
|
images.filter(i => i.Status !== 'complete').map((i) => [
|
||||||
i.ImageID,
|
i.ID,
|
||||||
{
|
{
|
||||||
Type: "image",
|
Type: "image",
|
||||||
ImageID: i.ImageID,
|
ImageID: i.ID,
|
||||||
ImageName: i.Image.ImageName,
|
ImageName: i.ImageName,
|
||||||
Status: i.Status,
|
Status: i.Status,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
|
@ -14,14 +14,10 @@ export type SearchImageStore = {
|
|||||||
Array<{ date: Date; images: JustTheImageWhatAreTheseNames }>
|
Array<{ date: Date; images: JustTheImageWhatAreTheseNames }>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
lists: Accessor<Awaited<ReturnType<typeof getUserImages>>["lists"]>;
|
stacks: Accessor<Awaited<ReturnType<typeof getUserImages>>["Stacks"]>;
|
||||||
|
|
||||||
userImages: Accessor<JustTheImageWhatAreTheseNames>;
|
userImages: Accessor<JustTheImageWhatAreTheseNames>;
|
||||||
|
|
||||||
processingImages: Accessor<
|
|
||||||
Awaited<ReturnType<typeof getUserImages>>["processingImages"] | undefined
|
|
||||||
>;
|
|
||||||
|
|
||||||
onRefetchImages: () => void;
|
onRefetchImages: () => void;
|
||||||
onDeleteImage: (imageID: string) => void;
|
onDeleteImage: (imageID: string) => void;
|
||||||
onDeleteImageFromStack: (stackID: string, imageID: string) => void;
|
onDeleteImageFromStack: (stackID: string, imageID: string) => void;
|
||||||
@ -41,7 +37,7 @@ export const SearchImageContextProvider: Component<ParentProps> = (props) => {
|
|||||||
// Sorted by day. But we could potentially add more in the future.
|
// Sorted by day. But we could potentially add more in the future.
|
||||||
const buckets: Record<string, JustTheImageWhatAreTheseNames> = {};
|
const buckets: Record<string, JustTheImageWhatAreTheseNames> = {};
|
||||||
|
|
||||||
for (const image of d.userImages) {
|
for (const image of d.UserImages) {
|
||||||
if (image.CreatedAt == null) {
|
if (image.CreatedAt == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -60,15 +56,12 @@ export const SearchImageContextProvider: Component<ParentProps> = (props) => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const processingImages = () => data()?.processingImages ?? [];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SearchImageContext.Provider
|
<SearchImageContext.Provider
|
||||||
value={{
|
value={{
|
||||||
imagesByDate: sortedImages,
|
imagesByDate: sortedImages,
|
||||||
lists: () => data()?.lists ?? [],
|
stacks: () => data()?.Stacks ?? [],
|
||||||
userImages: () => data()?.userImages ?? [],
|
userImages: () => data()?.UserImages ?? [],
|
||||||
processingImages,
|
|
||||||
onRefetchImages: refetch,
|
onRefetchImages: refetch,
|
||||||
onDeleteImage: (imageID: string) => {
|
onDeleteImage: (imageID: string) => {
|
||||||
deleteImage(imageID).then(refetch);
|
deleteImage(imageID).then(refetch);
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { getTokenProperties } from "@components/protected-route";
|
import { getTokenProperties } from "@components/protected-route";
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
import { jwtDecode } from "jwt-decode";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type InferOutput,
|
type InferOutput,
|
||||||
array,
|
array,
|
||||||
literal,
|
|
||||||
null_,
|
null_,
|
||||||
|
literal,
|
||||||
nullable,
|
nullable,
|
||||||
parse,
|
parse,
|
||||||
pipe,
|
pipe,
|
||||||
@ -172,91 +171,70 @@ export const sendImage = async (
|
|||||||
return parsedRes.output;
|
return parsedRes.output;
|
||||||
};
|
};
|
||||||
|
|
||||||
const imageMetaValidator = strictObject({
|
|
||||||
ID: pipe(string(), uuid()),
|
|
||||||
ImageName: string(),
|
|
||||||
Description: string(),
|
|
||||||
Image: null_(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const userImageValidator = strictObject({
|
const userImageValidator = strictObject({
|
||||||
ID: pipe(string(), uuid()),
|
ID: pipe(string(), uuid()),
|
||||||
CreatedAt: pipe(string()),
|
CreatedAt: string(),
|
||||||
ImageID: pipe(string(), uuid()),
|
|
||||||
UserID: pipe(string(), uuid()),
|
UserID: pipe(string(), uuid()),
|
||||||
Image: strictObject({
|
Description: string(),
|
||||||
...imageMetaValidator.entries,
|
|
||||||
ImageLists: pipe(nullable(array(
|
Image: null_(),
|
||||||
|
ImageName: string(),
|
||||||
|
|
||||||
|
Status: union([literal('not-started'), literal('in-progress'), literal('complete')]),
|
||||||
|
|
||||||
|
ImageStacks: pipe(nullable(array(
|
||||||
strictObject({
|
strictObject({
|
||||||
ID: pipe(string(), uuid()),
|
ID: pipe(string(), uuid()),
|
||||||
ImageID: pipe(string(), uuid()),
|
ImageID: pipe(string(), uuid()),
|
||||||
ListID: pipe(string(), uuid()),
|
ListID: pipe(string(), uuid()),
|
||||||
}),
|
}),
|
||||||
)), transform(l => l ?? [])),
|
)), transform(l => l ?? [])),
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const userProcessingImageValidator = strictObject({
|
const stackItem = strictObject({
|
||||||
ID: pipe(string(), uuid()),
|
|
||||||
ImageID: pipe(string(), uuid()),
|
|
||||||
UserID: pipe(string(), uuid()),
|
|
||||||
Image: imageMetaValidator,
|
|
||||||
Status: union([
|
|
||||||
literal("not-started"),
|
|
||||||
literal("in-progress"),
|
|
||||||
literal("complete"),
|
|
||||||
]),
|
|
||||||
});
|
|
||||||
|
|
||||||
const listValidator = strictObject({
|
|
||||||
ID: pipe(string(), uuid()),
|
|
||||||
UserID: pipe(string(), uuid()),
|
|
||||||
CreatedAt: pipe(string()),
|
|
||||||
Name: string(),
|
|
||||||
Description: nullable(string()),
|
|
||||||
|
|
||||||
Images: pipe(
|
|
||||||
nullable(
|
|
||||||
array(
|
|
||||||
strictObject({
|
|
||||||
ID: pipe(string(), uuid()),
|
|
||||||
ImageID: pipe(string(), uuid()),
|
|
||||||
ListID: pipe(string(), uuid()),
|
|
||||||
Items: array(
|
|
||||||
strictObject({
|
|
||||||
ID: pipe(string(), uuid()),
|
ID: pipe(string(), uuid()),
|
||||||
ImageID: pipe(string(), uuid()),
|
ImageID: pipe(string(), uuid()),
|
||||||
SchemaItemID: pipe(string(), uuid()),
|
SchemaItemID: pipe(string(), uuid()),
|
||||||
Value: string(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
transform((n) => n ?? []),
|
|
||||||
),
|
|
||||||
|
|
||||||
Schema: strictObject({
|
Value: string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const stackImage = strictObject({
|
||||||
ID: pipe(string(), uuid()),
|
ID: pipe(string(), uuid()),
|
||||||
ListID: pipe(string(), uuid()),
|
ImageID: pipe(string(), uuid()),
|
||||||
SchemaItems: array(
|
StackID: pipe(string(), uuid()),
|
||||||
strictObject({
|
|
||||||
ID: pipe(string(), uuid()),
|
Items: pipe(nullable(array(stackItem)), transform(l => l ?? [])),
|
||||||
SchemaID: pipe(string(), uuid()),
|
|
||||||
Item: string(),
|
|
||||||
Value: nullable(string()),
|
|
||||||
Description: string(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type List = InferOutput<typeof listValidator>;
|
const stackSchemaItem = strictObject({
|
||||||
|
ID: pipe(string(), uuid()),
|
||||||
|
StackID: pipe(string(), uuid()),
|
||||||
|
|
||||||
|
Description: string(),
|
||||||
|
Item: string(),
|
||||||
|
Value: string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const stackValidator = strictObject({
|
||||||
|
ID: pipe(string(), uuid()),
|
||||||
|
CreatedAt: string(),
|
||||||
|
UserID: pipe(string(), uuid()),
|
||||||
|
Description: string(),
|
||||||
|
|
||||||
|
Status: union([literal('not-started'), literal('in-progress'), literal('complete')]),
|
||||||
|
|
||||||
|
Name: string(),
|
||||||
|
|
||||||
|
Images: array(stackImage),
|
||||||
|
SchemaItems: array(stackSchemaItem),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type List = InferOutput<typeof stackValidator>;
|
||||||
|
|
||||||
const imageRequestValidator = strictObject({
|
const imageRequestValidator = strictObject({
|
||||||
userImages: array(userImageValidator),
|
UserImages: array(userImageValidator),
|
||||||
processingImages: array(userProcessingImageValidator),
|
Stacks: array(stackValidator),
|
||||||
lists: array(listValidator),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type JustTheImageWhatAreTheseNames = InferOutput<
|
export type JustTheImageWhatAreTheseNames = InferOutput<
|
||||||
@ -274,7 +252,7 @@ export const getUserImages = async (): Promise<
|
|||||||
|
|
||||||
const parsedRes = safeParse(imageRequestValidator, res);
|
const parsedRes = safeParse(imageRequestValidator, res);
|
||||||
if (!parsedRes.success) {
|
if (!parsedRes.success) {
|
||||||
console.log(parsedRes.issues)
|
console.log("Schema error: ", parsedRes.issues)
|
||||||
throw new Error(JSON.stringify(parsedRes.issues));
|
throw new Error(JSON.stringify(parsedRes.issues));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +288,7 @@ export const postCode = async (
|
|||||||
|
|
||||||
const parsedRes = safeParse(codeValidator, res);
|
const parsedRes = safeParse(codeValidator, res);
|
||||||
if (!parsedRes.success) {
|
if (!parsedRes.success) {
|
||||||
console.log(parsedRes.issues)
|
console.log("Schema error: ", parsedRes.issues)
|
||||||
throw new Error(JSON.stringify(parsedRes.issues));
|
throw new Error(JSON.stringify(parsedRes.issues));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import { Component, For } from "solid-js";
|
|||||||
import { createVirtualizer } from "@tanstack/solid-virtual";
|
import { createVirtualizer } from "@tanstack/solid-virtual";
|
||||||
import { ImageComponent } from "@components/image";
|
import { ImageComponent } from "@components/image";
|
||||||
import { chunkRows } from "./chunk";
|
import { chunkRows } from "./chunk";
|
||||||
import { deleteImage } from "@network/index";
|
|
||||||
|
|
||||||
type ImageOrDate =
|
type ImageOrDate =
|
||||||
| { type: "image"; ID: string[] }
|
| { type: "image"; ID: string[] }
|
||||||
@ -21,7 +20,7 @@ export const AllImages: Component = () => {
|
|||||||
items.push({ type: "date", date });
|
items.push({ type: "date", date });
|
||||||
const chunkedRows = chunkRows(3, images);
|
const chunkedRows = chunkRows(3, images);
|
||||||
for (const chunk of chunkedRows) {
|
for (const chunk of chunkedRows) {
|
||||||
items.push({ type: "image", ID: chunk.map((c) => c.ImageID) });
|
items.push({ type: "image", ID: chunk.map((c) => c.ID) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Component, For, createSignal } from "solid-js";
|
import { Component, For, createSignal } from "solid-js";
|
||||||
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
||||||
import { ListCard } from "@components/list-card";
|
import { StackCard } from "@components/list-card";
|
||||||
import { Button } from "@kobalte/core/button";
|
import { Button } from "@kobalte/core/button";
|
||||||
import { Dialog } from "@kobalte/core/dialog";
|
import { Dialog } from "@kobalte/core/dialog";
|
||||||
import { createList, ReachedListLimit } from "../../network";
|
import { createList, ReachedListLimit } from "../../network";
|
||||||
import { createToast } from "../../utils/show-toast";
|
import { createToast } from "../../utils/show-toast";
|
||||||
|
|
||||||
export const Categories: Component = () => {
|
export const Categories: Component = () => {
|
||||||
const { lists, onRefetchImages } = useSearchImageContext();
|
const { stacks, onRefetchImages } = useSearchImageContext();
|
||||||
|
|
||||||
const [title, setTitle] = createSignal("");
|
const [title, setTitle] = createSignal("");
|
||||||
const [description, setDescription] = createSignal("");
|
const [description, setDescription] = createSignal("");
|
||||||
@ -25,11 +25,11 @@ export const Categories: Component = () => {
|
|||||||
setTitle("");
|
setTitle("");
|
||||||
setDescription("");
|
setDescription("");
|
||||||
setShowForm(false);
|
setShowForm(false);
|
||||||
onRefetchImages(); // Refresh the lists
|
onRefetchImages(); // Refresh the stacks
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to create list:", error);
|
console.error("Failed to create list:", error);
|
||||||
if (error instanceof ReachedListLimit) {
|
if (error instanceof ReachedListLimit) {
|
||||||
createToast("Reached limit!", "You've reached your limit for new lists");
|
createToast("Reached limit!", "You've reached your limit for new stacks");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
@ -38,9 +38,9 @@ export const Categories: Component = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="rounded-xl bg-white p-4 flex flex-col gap-2">
|
<div class="rounded-xl bg-white p-4 flex flex-col gap-2">
|
||||||
<h2 class="text-xl font-bold">Generated Lists</h2>
|
<h2 class="text-xl font-bold">Generated stacks</h2>
|
||||||
<div class="w-full grid grid-cols-3 auto-rows-[minmax(100px,1fr)] gap-4">
|
<div class="w-full grid grid-cols-3 auto-rows-[minmax(100px,1fr)] gap-4">
|
||||||
<For each={lists()}>{(list) => <ListCard list={list} />}</For>
|
<For each={stacks()}>{(list) => <StackCard list={list} />}</For>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Component, For } from "solid-js";
|
import { Component, For } from "solid-js";
|
||||||
import { ImageComponent } from "@components/image";
|
import { ImageComponent } from "@components/image";
|
||||||
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
||||||
import { deleteImage } from "@network/index";
|
|
||||||
|
|
||||||
const NUMBER_OF_MAX_RECENT_IMAGES = 10;
|
const NUMBER_OF_MAX_RECENT_IMAGES = 10;
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ export const Recent: Component = () => {
|
|||||||
<h2 class="text-xl font-bold">Recent Screenshots</h2>
|
<h2 class="text-xl font-bold">Recent Screenshots</h2>
|
||||||
<div class="grid grid-cols-3 gap-4 place-items-center">
|
<div class="grid grid-cols-3 gap-4 place-items-center">
|
||||||
<For each={latestImages()}>
|
<For each={latestImages()}>
|
||||||
{(image) => <ImageComponent ID={image.ImageID} onDelete={onDeleteImage} />}
|
{(image) => <ImageComponent ID={image.ID} onDelete={onDeleteImage} />}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,15 +3,15 @@ import { useSearchImageContext } from "@contexts/SearchImageContext";
|
|||||||
import { useNavigate, useParams } from "@solidjs/router";
|
import { useNavigate, useParams } from "@solidjs/router";
|
||||||
import { For, type Component } from "solid-js";
|
import { For, type Component } from "solid-js";
|
||||||
import SolidjsMarkdown from "solidjs-markdown";
|
import SolidjsMarkdown from "solidjs-markdown";
|
||||||
import { ListCard } from "@components/list-card";
|
import { StackCard } from "@components/list-card";
|
||||||
|
|
||||||
export const ImagePage: Component = () => {
|
export const ImagePage: Component = () => {
|
||||||
const { imageId } = useParams<{ imageId: string }>();
|
const { imageId } = useParams<{ imageId: string }>();
|
||||||
const nav = useNavigate();
|
const nav = useNavigate();
|
||||||
|
|
||||||
const { userImages, lists, onDeleteImage } = useSearchImageContext();
|
const { userImages, stacks, onDeleteImage } = useSearchImageContext();
|
||||||
|
|
||||||
const image = () => userImages().find((i) => i.ImageID === imageId);
|
const image = () => userImages().find((i) => i.ID === imageId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main class="flex flex-col items-center gap-4">
|
<main class="flex flex-col items-center gap-4">
|
||||||
@ -24,10 +24,10 @@ export const ImagePage: Component = () => {
|
|||||||
<div class="w-full bg-white rounded-xl p-4 flex flex-col gap-4">
|
<div class="w-full bg-white rounded-xl p-4 flex flex-col gap-4">
|
||||||
<h2 class="font-bold text-2xl">Description</h2>
|
<h2 class="font-bold text-2xl">Description</h2>
|
||||||
<div class="grid grid-cols-3 gap-4">
|
<div class="grid grid-cols-3 gap-4">
|
||||||
<For each={image()?.Image.ImageLists}>
|
<For each={image()?.ImageStacks}>
|
||||||
{(imageList) => (
|
{(imageList) => (
|
||||||
<ListCard
|
<StackCard
|
||||||
list={lists().find((l) => l.ID === imageList.ListID)!}
|
list={stacks().find((l) => l.ID === imageList.ListID)!}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
@ -35,7 +35,7 @@ export const ImagePage: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="w-full bg-white rounded-xl p-4">
|
<div class="w-full bg-white rounded-xl p-4">
|
||||||
<h2 class="font-bold text-2xl">Description</h2>
|
<h2 class="font-bold text-2xl">Description</h2>
|
||||||
<SolidjsMarkdown>{image()?.Image.Description}</SolidjsMarkdown>
|
<SolidjsMarkdown>{image()?.Description}</SolidjsMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
@ -107,11 +107,11 @@ export const List: Component = () => {
|
|||||||
const { listId } = useParams();
|
const { listId } = useParams();
|
||||||
const nav = useNavigate();
|
const nav = useNavigate();
|
||||||
|
|
||||||
const { lists, onDeleteImageFromStack } = useSearchImageContext();
|
const { stacks, onDeleteImageFromStack } = useSearchImageContext();
|
||||||
|
|
||||||
const [accessToken] = createResource(getAccessToken);
|
const [accessToken] = createResource(getAccessToken);
|
||||||
|
|
||||||
const list = () => lists().find((l) => l.ID === listId);
|
const list = () => stacks().find((l) => l.ID === listId);
|
||||||
|
|
||||||
const handleDeleteList = async () => {
|
const handleDeleteList = async () => {
|
||||||
await deleteList(listId)
|
await deleteList(listId)
|
||||||
@ -148,11 +148,11 @@ export const List: Component = () => {
|
|||||||
<th class="px-6 py-4 text-left text-sm font-semibold text-neutral-900 border-r border-neutral-200 min-w-40">
|
<th class="px-6 py-4 text-left text-sm font-semibold text-neutral-900 border-r border-neutral-200 min-w-40">
|
||||||
Image
|
Image
|
||||||
</th>
|
</th>
|
||||||
<For each={l().Schema.SchemaItems}>
|
<For each={l().SchemaItems}>
|
||||||
{(item, index) => (
|
{(item, index) => (
|
||||||
<th
|
<th
|
||||||
class={`px-6 py-4 text-left text-sm font-semibold text-neutral-900 min-w-32 ${index() <
|
class={`px-6 py-4 text-left text-sm font-semibold text-neutral-900 min-w-32 ${index() <
|
||||||
l().Schema.SchemaItems
|
l().SchemaItems
|
||||||
.length -
|
.length -
|
||||||
1
|
1
|
||||||
? "border-r border-neutral-200"
|
? "border-r border-neutral-200"
|
||||||
|
@ -2,7 +2,7 @@ import { Component, createSignal, For } from "solid-js";
|
|||||||
import { Search } from "@kobalte/core/search";
|
import { Search } from "@kobalte/core/search";
|
||||||
import { IconSearch } from "@tabler/icons-solidjs";
|
import { IconSearch } from "@tabler/icons-solidjs";
|
||||||
import { useSearch } from "./search";
|
import { useSearch } from "./search";
|
||||||
import { deleteImage, JustTheImageWhatAreTheseNames } from "@network/index";
|
import { JustTheImageWhatAreTheseNames } from "@network/index";
|
||||||
import { ImageComponent } from "@components/image";
|
import { ImageComponent } from "@components/image";
|
||||||
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ export const SearchPage: Component = () => {
|
|||||||
<Search.Content class="container relative w-full rounded-xl bg-white p-4 grid grid-cols-3 gap-4">
|
<Search.Content class="container relative w-full rounded-xl bg-white p-4 grid grid-cols-3 gap-4">
|
||||||
<Search.Arrow />
|
<Search.Arrow />
|
||||||
<For each={searchItems()}>
|
<For each={searchItems()}>
|
||||||
{(item) => <ImageComponent ID={item.ImageID} onDelete={onDeleteImage} />}
|
{(item) => <ImageComponent ID={item.ID} onDelete={onDeleteImage} />}
|
||||||
</For>
|
</For>
|
||||||
<Search.NoResult>No result found</Search.NoResult>
|
<Search.NoResult>No result found</Search.NoResult>
|
||||||
</Search.Content>
|
</Search.Content>
|
||||||
|
Reference in New Issue
Block a user