Merge branch 'develop' into riobuenoDevelops/refine-integration
This commit is contained in:
commit
dec1fd29f5
|
@ -159,10 +159,7 @@ const UploadFileForm = () => {
|
||||||
state,
|
state,
|
||||||
removeFile,
|
removeFile,
|
||||||
cancelAll,
|
cancelAll,
|
||||||
} = useUppy({
|
} = useUppy();
|
||||||
uploader: "tus",
|
|
||||||
endpoint: import.meta.env.VITE_PUBLIC_TUS_ENDPOINT,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log({ state, files: getFiles() });
|
console.log({ state, files: getFiles() });
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import DropTarget, {type DropTargetOptions} from "./uppy-dropzone"
|
||||||
import {useSdk} from "~/components/lib/sdk-context.js";
|
import {useSdk} from "~/components/lib/sdk-context.js";
|
||||||
import UppyFileUpload from "~/components/lib/uppy-file-upload.js";
|
import UppyFileUpload from "~/components/lib/uppy-file-upload.js";
|
||||||
import {PROTOCOL_S5, Sdk} from "@lumeweb/portal-sdk";
|
import {PROTOCOL_S5, Sdk} from "@lumeweb/portal-sdk";
|
||||||
import {S5Client} from "@lumeweb/s5-js";
|
import {S5Client, HashProgressEvent} from "@lumeweb/s5-js";
|
||||||
|
|
||||||
const LISTENING_EVENTS = [
|
const LISTENING_EVENTS = [
|
||||||
"upload",
|
"upload",
|
||||||
|
@ -19,11 +19,7 @@ const LISTENING_EVENTS = [
|
||||||
"files-added"
|
"files-added"
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export function useUppy({
|
export function useUppy() {
|
||||||
endpoint
|
|
||||||
}: {
|
|
||||||
endpoint: string
|
|
||||||
}) {
|
|
||||||
const sdk = useSdk()
|
const sdk = useSdk()
|
||||||
|
|
||||||
const [uploadLimit, setUploadLimit] = useState<number>(0)
|
const [uploadLimit, setUploadLimit] = useState<number>(0)
|
||||||
|
@ -98,8 +94,24 @@ export function useUppy({
|
||||||
const file = uppyInstance.current?.getFile(fileID) as UppyFile
|
const file = uppyInstance.current?.getFile(fileID) as UppyFile
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (file.uploader === "tus") {
|
if (file.uploader === "tus") {
|
||||||
|
const hashProgressCb = (event: HashProgressEvent) => {
|
||||||
|
uppyInstance.current?.emit("preprocess-progress", file, {
|
||||||
|
uploadStarted: false,
|
||||||
|
bytesUploaded: 0,
|
||||||
|
preprocess: {
|
||||||
|
mode: "determinate",
|
||||||
|
message: "Hashing file...",
|
||||||
|
value: Math.round((event.total / event.total) * 100)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const options = await sdk.protocols!().get<S5Client>(PROTOCOL_S5).getSdk().getTusOptions(file.data as File, {}, {onHashProgress: hashProgressCb})
|
||||||
uppyInstance.current?.setFileState(fileID, {
|
uppyInstance.current?.setFileState(fileID, {
|
||||||
tus: await sdk.protocols!().get<S5Client>(PROTOCOL_S5).getSdk().getTusOptions(file.data as File)
|
tus: options,
|
||||||
|
meta: {
|
||||||
|
...options.metadata,
|
||||||
|
...file.meta,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +157,7 @@ export function useUppy({
|
||||||
})
|
})
|
||||||
|
|
||||||
if (useTus) {
|
if (useTus) {
|
||||||
uppy.use(Tus, { endpoint: endpoint, limit: 6 })
|
uppy.use(Tus, { limit: 6, parallelUploads: 10 })
|
||||||
uppy.addPreProcessor(tusPreprocessor)
|
uppy.addPreProcessor(tusPreprocessor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +207,7 @@ export function useUppy({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setState("idle")
|
setState("idle")
|
||||||
}, [targetRef, endpoint, uploadLimit])
|
}, [targetRef, uploadLimit])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import type {DataProvider, UpdateParams, UpdateResponse, HttpError} from "@refinedev/core";
|
||||||
|
import {SdkProvider} from "~/data/sdk-provider.js";
|
||||||
|
|
||||||
|
type AccountParams = {
|
||||||
|
email?: string;
|
||||||
|
password?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountData = AccountParams;
|
||||||
|
|
||||||
|
export const accountProvider: SdkProvider = {
|
||||||
|
getList: () => {
|
||||||
|
throw Error("Not Implemented")
|
||||||
|
},
|
||||||
|
getOne: () => {
|
||||||
|
throw Error("Not Implemented")
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
async update<TVariables extends AccountParams = AccountParams>(
|
||||||
|
params: UpdateParams<AccountParams>,
|
||||||
|
): Promise<UpdateResponse<AccountData>> {
|
||||||
|
if (params.variables.email && params.variables.password) {
|
||||||
|
const ret = await accountProvider.sdk?.account().updateEmail(params.variables.email, params.variables.password);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
if (ret instanceof Error) {
|
||||||
|
return Promise.reject(ret)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
data:
|
||||||
|
{
|
||||||
|
email: params.variables.email,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an empty response if params.variables is undefined
|
||||||
|
return {
|
||||||
|
data: {} as AccountParams,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
create: () => {
|
||||||
|
throw Error("Not Implemented")
|
||||||
|
},
|
||||||
|
deleteOne: () => {
|
||||||
|
throw Error("Not Implemented")
|
||||||
|
},
|
||||||
|
getApiUrl: () => "",
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import type {AuthProvider} from "@refinedev/core"
|
import type {AuthProvider, UpdatePasswordFormTypes} from "@refinedev/core"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
AuthActionResponse,
|
AuthActionResponse,
|
||||||
|
@ -8,7 +8,6 @@ import type {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} from "@refinedev/core/dist/interfaces/bindings/auth"
|
} from "@refinedev/core/dist/interfaces/bindings/auth"
|
||||||
import {Sdk} from "@lumeweb/portal-sdk";
|
import {Sdk} from "@lumeweb/portal-sdk";
|
||||||
import Cookies from 'universal-cookie';
|
|
||||||
import type {AccountInfoResponse} from "@lumeweb/portal-sdk";
|
import type {AccountInfoResponse} from "@lumeweb/portal-sdk";
|
||||||
|
|
||||||
export type AuthFormRequest = {
|
export type AuthFormRequest = {
|
||||||
|
@ -32,134 +31,116 @@ export type Identity = {
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PortalAuthProvider implements RequiredAuthProvider {
|
export interface UpdatePasswordFormRequest extends UpdatePasswordFormTypes{
|
||||||
constructor(apiUrl: string) {
|
currentPassword: string;
|
||||||
this._sdk = Sdk.create(apiUrl);
|
}
|
||||||
|
|
||||||
const methods: Array<keyof AuthProvider> = [
|
export const createPortalAuthProvider = (sdk: Sdk): AuthProvider => {
|
||||||
'login',
|
const maybeSetupAuth = (): void => {
|
||||||
'logout',
|
const jwt = sdk.account().jwtToken;
|
||||||
'check',
|
if (jwt) {
|
||||||
'onError',
|
sdk.setAuthToken(jwt);
|
||||||
'register',
|
}
|
||||||
'forgotPassword',
|
};
|
||||||
'updatePassword',
|
|
||||||
'getPermissions',
|
|
||||||
'getIdentity',
|
|
||||||
];
|
|
||||||
|
|
||||||
methods.forEach((method) => {
|
return {
|
||||||
this[method] = this[method]?.bind(this) as any;
|
async login(params: AuthFormRequest): Promise<AuthActionResponse> {
|
||||||
});
|
const ret = await sdk.account().login({
|
||||||
}
|
email: params.email,
|
||||||
|
password: params.password,
|
||||||
|
});
|
||||||
|
|
||||||
private _sdk: Sdk;
|
let redirectTo: string | undefined;
|
||||||
|
|
||||||
get sdk(): Sdk {
|
if (ret) {
|
||||||
return this._sdk;
|
redirectTo = params.redirectTo;
|
||||||
}
|
if (!redirectTo) {
|
||||||
|
redirectTo = ret ? "/dashboard" : "/login";
|
||||||
public static create(apiUrl: string): AuthProvider {
|
}
|
||||||
return new PortalAuthProvider(apiUrl);
|
sdk.setAuthToken(sdk.account().jwtToken);
|
||||||
}
|
|
||||||
|
|
||||||
async login(params: AuthFormRequest): Promise<AuthActionResponse> {
|
|
||||||
const ret = await this._sdk.account().login({
|
|
||||||
email: params.email,
|
|
||||||
password: params.password,
|
|
||||||
})
|
|
||||||
|
|
||||||
let redirectTo: string | undefined;
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
redirectTo = params.redirectTo;
|
|
||||||
if (!redirectTo) {
|
|
||||||
redirectTo = ret ? "/dashboard" : "/login";
|
|
||||||
}
|
}
|
||||||
this._sdk.setAuthToken(this._sdk.account().jwtToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: ret,
|
success: ret,
|
||||||
redirectTo,
|
redirectTo,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
|
|
||||||
async logout(params: any): Promise<AuthActionResponse> {
|
async logout(params: any): Promise<AuthActionResponse> {
|
||||||
let ret = await this._sdk.account().logout();
|
let ret = await sdk.account().logout();
|
||||||
return {success: ret, redirectTo: "/login"};
|
return {success: ret, redirectTo: "/login"};
|
||||||
}
|
},
|
||||||
|
|
||||||
async check(params?: any): Promise<CheckResponse> {
|
async check(params?: any): Promise<CheckResponse> {
|
||||||
this.maybeSetupAuth();
|
const ret = await sdk.account().ping();
|
||||||
|
|
||||||
const ret = await this._sdk.account().ping();
|
if (ret) {
|
||||||
|
maybeSetupAuth();
|
||||||
|
}
|
||||||
|
|
||||||
return {authenticated: ret, redirectTo: ret ? undefined : "/login"};
|
return {authenticated: ret, redirectTo: ret ? undefined : "/login"};
|
||||||
}
|
},
|
||||||
|
|
||||||
async onError(error: any): Promise<OnErrorResponse> {
|
async onError(error: any): Promise<OnErrorResponse> {
|
||||||
const cookies = new Cookies();
|
return {logout: true};
|
||||||
return {logout: true};
|
},
|
||||||
}
|
|
||||||
|
|
||||||
async register(params: RegisterFormRequest): Promise<AuthActionResponse> {
|
async register(params: RegisterFormRequest): Promise<AuthActionResponse> {
|
||||||
const ret = await this._sdk.account().register({
|
const ret = await sdk.account().register({
|
||||||
email: params.email,
|
email: params.email,
|
||||||
password: params.password,
|
password: params.password,
|
||||||
first_name: params.firstName,
|
first_name: params.firstName,
|
||||||
last_name: params.lastName,
|
last_name: params.lastName,
|
||||||
});
|
});
|
||||||
return {success: ret, redirectTo: ret ? "/dashboard" : undefined};
|
return {success: ret, redirectTo: ret ? "/dashboard" : undefined};
|
||||||
}
|
},
|
||||||
|
|
||||||
async forgotPassword(params: any): Promise<AuthActionResponse> {
|
async forgotPassword(params: any): Promise<AuthActionResponse> {
|
||||||
return {success: true};
|
return {success: true};
|
||||||
}
|
},
|
||||||
|
|
||||||
async updatePassword(params: any): Promise<AuthActionResponse> {
|
async updatePassword(params: UpdatePasswordFormRequest): Promise<AuthActionResponse> {
|
||||||
return {success: true};
|
maybeSetupAuth();
|
||||||
}
|
const ret = await sdk.account().updatePassword(params.currentPassword, params.password as string);
|
||||||
|
|
||||||
async getPermissions(params?: Record<string, any>): Promise<AuthActionResponse> {
|
if (ret) {
|
||||||
return {success: true};
|
if (ret instanceof Error) {
|
||||||
}
|
return {
|
||||||
|
success: false,
|
||||||
|
error: ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getIdentity(params?: Identity): Promise<IdentityResponse> {
|
return {
|
||||||
this.maybeSetupAuth();
|
success: true
|
||||||
const ret = await this._sdk.account().info();
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
if (!ret) {
|
async getPermissions(params?: Record<string, any>): Promise<AuthActionResponse> {
|
||||||
return {identity: null};
|
return {success: true};
|
||||||
}
|
},
|
||||||
|
|
||||||
const acct = ret as AccountInfoResponse;
|
async getIdentity(params?: Identity): Promise<IdentityResponse> {
|
||||||
|
maybeSetupAuth();
|
||||||
|
const ret = await sdk.account().info();
|
||||||
|
|
||||||
return {
|
if (!ret) {
|
||||||
id: acct.id,
|
return {identity: null};
|
||||||
firstName: acct.first_name,
|
}
|
||||||
lastName: acct.last_name,
|
|
||||||
email: acct.email,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeSetupAuth(): void {
|
const acct = ret as AccountInfoResponse;
|
||||||
const cookies = new Cookies();
|
|
||||||
const jwtCookie = cookies.get('auth_token');
|
|
||||||
if (jwtCookie) {
|
|
||||||
this._sdk.setAuthToken(jwtCookie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RequiredAuthProvider extends AuthProvider {
|
return {
|
||||||
login: AuthProvider['login'];
|
id: acct.id,
|
||||||
logout: AuthProvider['logout'];
|
firstName: acct.first_name,
|
||||||
check: AuthProvider['check'];
|
lastName: acct.last_name,
|
||||||
onError: AuthProvider['onError'];
|
email: acct.email,
|
||||||
register: AuthProvider['register'];
|
};
|
||||||
forgotPassword: AuthProvider['forgotPassword'];
|
},
|
||||||
updatePassword: AuthProvider['updatePassword'];
|
};
|
||||||
getPermissions: AuthProvider['getPermissions'];
|
};
|
||||||
getIdentity: AuthProvider['getIdentity'];
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import type { DataProvider } from "@refinedev/core";
|
import type { DataProvider } from "@refinedev/core";
|
||||||
|
import {SdkProvider} from "~/data/sdk-provider.js";
|
||||||
|
|
||||||
export const defaultProvider: DataProvider = {
|
export const fileProvider: SdkProvider = {
|
||||||
getList: () => { throw Error("Not Implemented") },
|
getList: () => { throw Error("Not Implemented") },
|
||||||
getOne: () => { throw Error("Not Implemented") },
|
getOne: () => { throw Error("Not Implemented") },
|
||||||
update: () => { throw Error("Not Implemented") },
|
update: () => { throw Error("Not Implemented") },
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type {AuthProvider, DataProvider} from "@refinedev/core";
|
||||||
|
import {fileProvider} from "~/data/file-provider.js";
|
||||||
|
import {Sdk} from "@lumeweb/portal-sdk";
|
||||||
|
import {accountProvider} from "~/data/account-provider.js";
|
||||||
|
import type {SdkProvider} from "~/data/sdk-provider.js";
|
||||||
|
import {createPortalAuthProvider} from "~/data/auth-provider.js";
|
||||||
|
|
||||||
|
interface DataProviders {
|
||||||
|
default: SdkProvider;
|
||||||
|
auth: AuthProvider;
|
||||||
|
|
||||||
|
[key: string]: SdkProvider | AuthProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
let providers: DataProviders;
|
||||||
|
|
||||||
|
export function getProviders(sdk: Sdk) {
|
||||||
|
if (providers) {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
accountProvider.sdk = sdk;
|
||||||
|
fileProvider.sdk = sdk;
|
||||||
|
providers = {
|
||||||
|
default: accountProvider,
|
||||||
|
auth: createPortalAuthProvider(sdk),
|
||||||
|
files: fileProvider,
|
||||||
|
};
|
||||||
|
|
||||||
|
return providers;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type {ResourceProps} from "@refinedev/core";
|
||||||
|
|
||||||
|
const resources: ResourceProps[] = [
|
||||||
|
{
|
||||||
|
name: 'account',
|
||||||
|
meta: {
|
||||||
|
dataProviderName: 'default',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'file',
|
||||||
|
meta: {
|
||||||
|
dataProviderName: 'files',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default resources;
|
|
@ -0,0 +1,6 @@
|
||||||
|
import {DataProvider} from "@refinedev/core";
|
||||||
|
import {Sdk} from "@lumeweb/portal-sdk";
|
||||||
|
|
||||||
|
export interface SdkProvider extends DataProvider {
|
||||||
|
sdk?: Sdk;
|
||||||
|
}
|
31
app/root.tsx
31
app/root.tsx
|
@ -1,24 +1,18 @@
|
||||||
import {
|
import {Links, Meta, Outlet, Scripts, ScrollRestoration,} from "@remix-run/react";
|
||||||
Links,
|
|
||||||
Meta,
|
|
||||||
Outlet,
|
|
||||||
Scripts,
|
|
||||||
ScrollRestoration,
|
|
||||||
} from "@remix-run/react";
|
|
||||||
|
|
||||||
import stylesheet from "./tailwind.css?url";
|
import stylesheet from "./tailwind.css?url";
|
||||||
import type { LinksFunction } from "@remix-run/node";
|
import type {LinksFunction} from "@remix-run/node";
|
||||||
|
|
||||||
// Supports weights 200-800
|
// Supports weights 200-800
|
||||||
import '@fontsource-variable/manrope';
|
import '@fontsource-variable/manrope';
|
||||||
import {Refine} from "@refinedev/core";
|
import {Refine} from "@refinedev/core";
|
||||||
import routerProvider from "@refinedev/remix-router";
|
import routerProvider from "@refinedev/remix-router";
|
||||||
import { defaultProvider } from "~/data/file-provider";
|
|
||||||
import {PortalAuthProvider} from "~/data/auth-provider";
|
|
||||||
import { notificationProvider } from "~/data/notification-provider";
|
import { notificationProvider } from "~/data/notification-provider";
|
||||||
import {SdkContextProvider} from "~/components/lib/sdk-context";
|
import {SdkContextProvider} from "~/components/lib/sdk-context";
|
||||||
import { Toaster } from "~/components/ui/toaster";
|
import { Toaster } from "~/components/ui/toaster";
|
||||||
|
import {getProviders} from "~/data/providers.js";
|
||||||
|
import {Sdk} from "@lumeweb/portal-sdk";
|
||||||
|
import resources from "~/data/resources.js";
|
||||||
|
|
||||||
export const links: LinksFunction = () => [
|
export const links: LinksFunction = () => [
|
||||||
{ rel: "stylesheet", href: stylesheet },
|
{ rel: "stylesheet", href: stylesheet },
|
||||||
|
@ -44,19 +38,18 @@ export function Layout({children}: { children: React.ReactNode }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const auth = PortalAuthProvider.create("https://alpha.pinner.xyz")
|
const sdk = Sdk.create(import.meta.env.VITE_PORTAL_URL)
|
||||||
|
const providers = getProviders(sdk);
|
||||||
return (
|
return (
|
||||||
<Refine
|
<Refine
|
||||||
authProvider={auth}
|
authProvider={providers.auth}
|
||||||
routerProvider={routerProvider}
|
routerProvider={routerProvider}
|
||||||
dataProvider={defaultProvider}
|
|
||||||
notificationProvider={notificationProvider}
|
notificationProvider={notificationProvider}
|
||||||
resources={[
|
dataProvider={providers.default}
|
||||||
{ name: 'files' },
|
resources={resources}
|
||||||
{ name: 'users' }
|
options={{disableTelemetry: true}}
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<SdkContextProvider sdk={(auth as PortalAuthProvider).sdk}>
|
<SdkContextProvider sdk={sdk}>
|
||||||
<Outlet/>
|
<Outlet/>
|
||||||
</SdkContextProvider>
|
</SdkContextProvider>
|
||||||
</Refine>
|
</Refine>
|
||||||
|
|
|
@ -3,10 +3,11 @@ import { getZodConstraint, parseWithZod } from "@conform-to/zod";
|
||||||
import { DialogClose } from "@radix-ui/react-dialog";
|
import { DialogClose } from "@radix-ui/react-dialog";
|
||||||
import { Cross2Icon } from "@radix-ui/react-icons";
|
import { Cross2Icon } from "@radix-ui/react-icons";
|
||||||
import {
|
import {
|
||||||
BaseKey,
|
Authenticated,
|
||||||
useGetIdentity,
|
BaseKey,
|
||||||
useUpdate,
|
useGetIdentity,
|
||||||
useUpdatePassword,
|
useUpdate,
|
||||||
|
useUpdatePassword,
|
||||||
} from "@refinedev/core";
|
} from "@refinedev/core";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
@ -40,6 +41,7 @@ import { Input } from "~/components/ui/input";
|
||||||
import { UsageCard } from "~/components/usage-card";
|
import { UsageCard } from "~/components/usage-card";
|
||||||
|
|
||||||
import QRImg from "~/images/QR.png";
|
import QRImg from "~/images/QR.png";
|
||||||
|
import {UpdatePasswordFormRequest} from "~/data/auth-provider.js";
|
||||||
|
|
||||||
export default function MyAccount() {
|
export default function MyAccount() {
|
||||||
const { data: identity } = useGetIdentity<{ email: string }>();
|
const { data: identity } = useGetIdentity<{ email: string }>();
|
||||||
|
@ -52,7 +54,8 @@ export default function MyAccount() {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GeneralLayout>
|
<Authenticated key="account" v3LegacyAuthProviderCompatible>
|
||||||
|
<GeneralLayout>
|
||||||
<h1 className="text-lg font-bold mb-4">My Account</h1>
|
<h1 className="text-lg font-bold mb-4">My Account</h1>
|
||||||
<Dialog
|
<Dialog
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
|
@ -211,6 +214,7 @@ export default function MyAccount() {
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</GeneralLayout>
|
</GeneralLayout>
|
||||||
|
</Authenticated>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,10 +251,11 @@ const ChangeEmailForm = ({ currentValue }: { currentValue: string }) => {
|
||||||
const data = Object.fromEntries(new FormData(e.currentTarget).entries());
|
const data = Object.fromEntries(new FormData(e.currentTarget).entries());
|
||||||
console.log(identity);
|
console.log(identity);
|
||||||
updateEmail({
|
updateEmail({
|
||||||
resource: "users",
|
resource: "account",
|
||||||
id: identity?.id || "",
|
id: "",
|
||||||
values: {
|
values: {
|
||||||
email: data.email.toString(),
|
email: data.email.toString(),
|
||||||
|
password: data.password.toString(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -292,7 +297,7 @@ const ChangeEmailForm = ({ currentValue }: { currentValue: string }) => {
|
||||||
|
|
||||||
const ChangePasswordSchema = z
|
const ChangePasswordSchema = z
|
||||||
.object({
|
.object({
|
||||||
currentPassword: z.string().email(),
|
currentPassword: z.string(),
|
||||||
newPassword: z.string(),
|
newPassword: z.string(),
|
||||||
retypePassword: z.string(),
|
retypePassword: z.string(),
|
||||||
})
|
})
|
||||||
|
@ -311,7 +316,7 @@ const ChangePasswordForm = () => {
|
||||||
const { mutate: updatePassword } = useUpdatePassword<{ password: string }>();
|
const { mutate: updatePassword } = useUpdatePassword<{ password: string }>();
|
||||||
const [form, fields] = useForm({
|
const [form, fields] = useForm({
|
||||||
id: "login",
|
id: "login",
|
||||||
constraint: getZodConstraint(ChangeEmailSchema),
|
constraint: getZodConstraint(ChangePasswordSchema),
|
||||||
onValidate({ formData }) {
|
onValidate({ formData }) {
|
||||||
return parseWithZod(formData, { schema: ChangePasswordSchema });
|
return parseWithZod(formData, { schema: ChangePasswordSchema });
|
||||||
},
|
},
|
||||||
|
@ -322,7 +327,7 @@ const ChangePasswordForm = () => {
|
||||||
const data = Object.fromEntries(new FormData(e.currentTarget).entries());
|
const data = Object.fromEntries(new FormData(e.currentTarget).entries());
|
||||||
|
|
||||||
updatePassword({
|
updatePassword({
|
||||||
password: data.newPassword.toString(),
|
password: data.newPassword.toString(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -408,10 +413,7 @@ const ChangeAvatarForm = () => {
|
||||||
state,
|
state,
|
||||||
removeFile,
|
removeFile,
|
||||||
cancelAll,
|
cancelAll,
|
||||||
} = useUppy({
|
} = useUppy();
|
||||||
uploader: "tus",
|
|
||||||
endpoint: import.meta.env.VITE_PUBLIC_TUS_ENDPOINT,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log({ state, files: getFiles() });
|
console.log({ state, files: getFiles() });
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,15 @@
|
||||||
"dev": "remix vite:dev",
|
"dev": "remix vite:dev",
|
||||||
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
|
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"typecheck": "tsc"
|
"typecheck": "tsc",
|
||||||
|
"patch-package": "patch-package",
|
||||||
|
"postinstall": "patch-package"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@conform-to/react": "^1.0.2",
|
"@conform-to/react": "^1.0.2",
|
||||||
"@conform-to/zod": "^1.0.2",
|
"@conform-to/zod": "^1.0.2",
|
||||||
"@fontsource-variable/manrope": "^5.0.19",
|
"@fontsource-variable/manrope": "^5.0.19",
|
||||||
"@lumeweb/portal-sdk": "0.0.0-20240318183202",
|
"@lumeweb/portal-sdk": "0.0.0-20240319140708",
|
||||||
"@radix-ui/react-avatar": "^1.0.4",
|
"@radix-ui/react-avatar": "^1.0.4",
|
||||||
"@radix-ui/react-checkbox": "^1.0.4",
|
"@radix-ui/react-checkbox": "^1.0.4",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
|
@ -44,7 +46,6 @@
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"universal-cookie": "^7.1.0",
|
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_PORTAL_API_URL: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
Loading…
Reference in New Issue