fix: small fixes

This commit is contained in:
Juan Di Toro 2024-03-22 18:53:39 +01:00
parent e1ca45f1f1
commit c9de506c56
5 changed files with 331 additions and 274 deletions

View File

@ -1,51 +1,62 @@
import { useMutation } from "@tanstack/react-query";
import { useContext } from "react";
import { useNotification } from "@refinedev/core";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useCallback, useContext } from "react";
import { PinningProcess } from "~/data/pinning";
import { PinningContext } from "~/providers/PinningProvider";
// TODO: Adapt to real API
export const usePinning = () => {
const queryClient = useQueryClient();
const context = useContext(PinningContext);
const { open } = useNotification();
const { mutate } = useMutation({
mutationKey: ["pin-progress"],
mutationFn: async (variables: { cid: string, type: "pin" | "unpin" }) => {
const { cid, type } = variables;
switch (type) {
case "pin": {
const { mutate: pinMutation } = useMutation({
mutationKey: ["pin-mutation"],
mutationFn: async (variables: { cid: string }) => {
const { cid } = variables;
const response = await PinningProcess.pin(cid);
if (!response.success) {
open?.({
type: "destructive",
message: "Erorr pinning " + cid,
type: "error",
message: `Error pinning ${cid}`,
description: response.message,
});
}
break;
}
case "unpin": {
queryClient.invalidateQueries({ queryKey: ["pin-progress"] });
},
});
const { mutate: unpinMutation } = useMutation({
mutationKey: ["unpin-mutation"],
mutationFn: async (variables: { cid: string }) => {
const { cid } = variables;
const response = await PinningProcess.unpin(cid);
if (!response.success) {
open?.({
type: "destructive",
message: "Erorr removing " + cid,
type: "error",
message: `Error removing ${cid}`,
description: response.message,
});
}
break;
}
}
context.queryClient.invalidateQueries({ queryKey: ["pin-progress"] })
}
queryClient.invalidateQueries({ queryKey: ["pin-progress"] });
},
});
const bulkPin = useCallback(
(cids: string[]) => {
for (const cid of cids) {
pinMutation({ cid });
}
},
[pinMutation],
);
return {
...context.query,
mutate
pin: pinMutation,
unpin: unpinMutation,
bulkPin,
};
};

View File

@ -1,11 +1,11 @@
import {
QueryClient,
UseQueryResult,
type QueryClient,
type UseQueryResult,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createContext, useContext } from "react";
import { PinningProcess, PinningStatus } from "~/data/pinning";
import { PinningProcess, type PinningStatus } from "~/data/pinning";
export interface IPinningData {
cid: string;

View File

@ -1,41 +1,47 @@
import {Links, Meta, Outlet, Scripts, ScrollRestoration,} from "@remix-run/react";
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import stylesheet from "./tailwind.css?url";
import type {LinksFunction} from "@remix-run/node";
import type { LinksFunction } from "@remix-run/node";
// Supports weights 200-800
import '@fontsource-variable/manrope';
import {Refine} from "@refinedev/core";
import "@fontsource-variable/manrope";
import { Refine } from "@refinedev/core";
import routerProvider from "@refinedev/remix-router";
import {notificationProvider} from "~/data/notification-provider";
import {SdkContextProvider, useSdk} from "~/components/lib/sdk-context";
import {Toaster} from "~/components/ui/toaster";
import {getProviders} from "~/data/providers.js";
import {Sdk} from "@lumeweb/portal-sdk";
import { notificationProvider } from "~/data/notification-provider";
import { SdkContextProvider, useSdk } from "~/components/lib/sdk-context";
import { Toaster } from "~/components/ui/toaster";
import { getProviders } from "~/data/providers.js";
import { Sdk } from "@lumeweb/portal-sdk";
import resources from "~/data/resources.js";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {useMemo} from "react";
import { useMemo } from "react";
export const links: LinksFunction = () => [
{rel: "stylesheet", href: stylesheet},
{ rel: "stylesheet", href: stylesheet },
];
const queryClient = new QueryClient();
export function Layout({children}: { children: React.ReactNode }) {
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<Meta/>
<Links/>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body className="overflow-hidden">
{children}
<Toaster/>
<ScrollRestoration/>
<Scripts/>
<Toaster />
<ScrollRestoration />
<Scripts />
</body>
</html>
);
@ -52,24 +58,21 @@ function App() {
notificationProvider={notificationProvider}
dataProvider={{
default: providers.default,
files: providers.files
files: providers.files,
}}
resources={resources}
options={{disableTelemetry: true}}
>
<SdkContextProvider sdk={sdk}>
<Outlet/>
</SdkContextProvider>
options={{ disableTelemetry: true }}>
<Outlet />
</Refine>
</QueryClientProvider>
);
}
export default function Root() {
const sdk = Sdk.create(import.meta.env.VITE_PORTAL_URL)
const sdk = Sdk.create(import.meta.env.VITE_PORTAL_URL);
return (
<SdkContextProvider sdk={sdk}>
<App/>
<App />
</SdkContextProvider>
);
}

View File

@ -41,7 +41,7 @@ import { Input } from "~/components/ui/input";
import { UsageCard } from "~/components/usage-card";
import QRImg from "~/images/QR.png";
import type {UpdatePasswordFormRequest} from "~/data/auth-provider";
import type { UpdatePasswordFormRequest } from "~/data/auth-provider";
export default function MyAccount() {
const { data: identity } = useGetIdentity<{ email: string }>();
@ -85,9 +85,13 @@ export default function MyAccount() {
<ManagementCard>
<ManagementCardAvatar
button={
<DialogTrigger asChild className="absolute bottom-0 right-0 z-50">
<DialogTrigger
asChild
className="absolute bottom-0 right-0 z-50">
<Button
onClick={() => setModal({ ...openModal, changeAvatar: true })}
onClick={() =>
setModal({ ...openModal, changeAvatar: true })
}
variant="outline"
className=" flex items-center w-10 h-10 p-0 border-white rounded-full justiyf-center hover:bg-secondary-2">
<EditIcon />
@ -105,7 +109,9 @@ export default function MyAccount() {
<DialogTrigger asChild>
<Button
className="h-12 gap-x-2"
onClick={() => setModal({ ...openModal, changeEmail: true })}>
onClick={() =>
setModal({ ...openModal, changeEmail: true })
}>
<AddIcon />
Change Email Address
</Button>
@ -147,7 +153,9 @@ export default function MyAccount() {
</ManagementCardFooter>
</ManagementCard>
<ManagementCard>
<ManagementCardTitle>Two-Factor Authentication</ManagementCardTitle>
<ManagementCardTitle>
Two-Factor Authentication
</ManagementCardTitle>
<ManagementCardContent>
Improve security by enabling 2FA.
</ManagementCardContent>
@ -313,7 +321,8 @@ const ChangePasswordSchema = z
});
const ChangePasswordForm = () => {
const { mutate: updatePassword } = useUpdatePassword<UpdatePasswordFormRequest>();
const { mutate: updatePassword } =
useUpdatePassword<UpdatePasswordFormRequest>();
const [form, fields] = useForm({
id: "login",
constraint: getZodConstraint(ChangePasswordSchema),

View File

@ -14,6 +14,10 @@ import {
DialogTrigger,
} from "~/components/ui/dialog";
import { Field } from "~/components/forms";
import { z } from "zod";
import { getFormProps, useForm } from "@conform-to/react";
import { getZodConstraint, parseWithZod } from "@conform-to/zod";
import { usePinning } from "~/hooks/usePinning";
export default function FileManager() {
return (
@ -72,25 +76,55 @@ export default function FileManager() {
dataProviderName="files"
/>
<DialogContent>
<DialogHeader>
<DialogTitle>Pin Content</DialogTitle>
</DialogHeader>
<form action="" className="w-full flex flex-col gap-y-4">
<Field
inputProps={{
name: "cids",
placeholder: "Comma separated CIDs",
}}
labelProps={{ htmlFor: "cids", children: "Content to Pin" }}
/>
<Button type="submit" className="w-full">
Pin Content
</Button>
</form>
<PinFilesForm />
</DialogContent>
</Dialog>
</GeneralLayout>
</Authenticated>
);
}
const PinFilesSchema = z.object({
cids: z.string().transform((value) => value.split(",")),
});
const PinFilesForm = () => {
const { bulkPin } = usePinning();
const [form, fields] = useForm({
id: "pin-files",
constraint: getZodConstraint(PinFilesSchema),
onValidate({ formData }) {
return parseWithZod(formData, { schema: PinFilesSchema });
},
shouldValidate: "onSubmit",
onSubmit(e, { submission }) {
if (submission?.status === "success") {
const value = submission.value;
bulkPin(value.cids);
}
},
});
return (
<>
<DialogHeader>
<DialogTitle>Pin Content</DialogTitle>
</DialogHeader>
<form {...getFormProps(form)} className="w-full flex flex-col gap-y-4">
<Field
inputProps={{
name: fields.cids.name,
placeholder: "Comma separated CIDs",
}}
labelProps={{ htmlFor: "cids", children: "Content to Pin" }}
errors={fields.cids.errors}
/>
<Button type="submit" className="w-full">
Pin Content
</Button>
</form>
</>
);
};