diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 2c58a9403..8db0f2440 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@instill-ai/toolkit", - "version": "0.80.4-rc.2", + "version": "0.80.4-rc.5", "description": "Instill AI's frontend toolkit", "repository": "https://github.com/instill-ai/design-system.git", "bugs": "https://github.com/instill-ai/design-system/issues", diff --git a/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx b/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx new file mode 100644 index 000000000..6b060e82d --- /dev/null +++ b/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx @@ -0,0 +1,141 @@ +import * as React from "react"; +import { Button, Dialog, Form, Input } from "@instill-ai/design-system"; +import { GeneralUseFormReturn } from "../lib"; +import { FormLabel } from "../view/settings/FormLabel"; +import AvatarEditor from "react-avatar-editor"; +import { UseFormReturn } from "react-hook-form"; + +export const UploadAvatarFieldWithCrop = ({ + fieldName, + form, + placeholder, +}: { + fieldName: string; + form: UseFormReturn; + placeholder?: React.ReactNode; +}) => { + const [profileAvatar, setProfileAvatar] = React.useState< + string | File | null + >(null); + const [openProfileAvatar, setOpenProfileAvatar] = + React.useState(false); + const editorRef = React.useRef(null); + + function handleSetProfilePicture() { + // Save the cropped image as a file or perform any other actions here + // For simplicity, let's assume you have a function to handle image upload + const croppedImage = editorRef.current + ?.getImageScaledToCanvas() + ?.toDataURL(); + setProfileAvatar(croppedImage ?? null); + form.setValue(fieldName, croppedImage ?? undefined); + // Close the dialog or perform any other actions + setOpenProfileAvatar(false); + } + + function handleCancelCropProfile() { + setOpenProfileAvatar(false); + setProfileAvatar(null); + + form.resetField("profile.avatar"); + } + + return ( + + { + return ( + + + +
+ +
+
+ +
+ ); + }} + /> + + + + Crop your image + +
+ {profileAvatar ? ( + + ) : null} +
+
+ + +
+
+
+
+ ); +}; diff --git a/packages/toolkit/src/components/index.ts b/packages/toolkit/src/components/index.ts index ebe981439..eda71405f 100644 --- a/packages/toolkit/src/components/index.ts +++ b/packages/toolkit/src/components/index.ts @@ -28,5 +28,6 @@ export * from "./ReferenceHintTag"; export * from "./ReferenceHintDataTypeTag"; export * from "./cells"; export * from "./TableError"; +export * from "./UploadAvatarFieldWithCrop"; export * from "./UserProfileCard"; export * from "./WarnUnsavedChangesDialog"; diff --git a/packages/toolkit/src/view/settings/user/UserProfileTab.tsx b/packages/toolkit/src/view/settings/user/UserProfileTab.tsx index 9f087ba47..4579d3071 100644 --- a/packages/toolkit/src/view/settings/user/UserProfileTab.tsx +++ b/packages/toolkit/src/view/settings/user/UserProfileTab.tsx @@ -1,12 +1,11 @@ import * as z from "zod"; import * as React from "react"; -import { Setting, instillUserRoles } from ".."; +import { Setting } from ".."; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { Button, - Dialog, Form, Input, Switch, @@ -24,8 +23,7 @@ import { useAuthenticatedUser, } from "../../../lib"; import { FormLabel } from "../FormLabel"; -import { LoadingSpin } from "../../../components"; -import AvatarEditor from "react-avatar-editor"; +import { LoadingSpin, UploadAvatarFieldWithCrop } from "../../../components"; import { useUpdateAuthenticatedUser } from "../../../lib"; export const UserProfileTabSchema = z.object({ @@ -59,13 +57,6 @@ export const UserProfileTab = () => { const { amplitudeIsInit } = useAmplitudeCtx(); const { accessToken, enabledQuery } = useInstillStore(useShallow(selector)); const { toast } = useToast(); - const [profileAvatar, setProfileAvatar] = React.useState< - string | File | null - >(null); - const [isOpenProfileAvatar, setIsOpenProfileAvatar] = - React.useState(false); - - const editorRef = React.useRef(null); const me = useAuthenticatedUser({ accessToken, @@ -117,24 +108,6 @@ export const UserProfileTab = () => { } } - function handleSetProfilePicture() { - // Save the cropped image as a file or perform any other actions here - // For simplicity, let's assume you have a function to handle image upload - const croppedImage = editorRef.current - ?.getImageScaledToCanvas() - ?.toDataURL(); - setProfileAvatar(croppedImage ?? null); - // Close the dialog or perform any other actions - setIsOpenProfileAvatar(false); - } - - function handleCancelCropProfile() { - setIsOpenProfileAvatar(false); - setProfileAvatar(null); - - form.resetField("profile.avatar"); - } - return ( { description="This will be displayed on your profile." /> - { - return ( - - - -
- -
-
- -
- ); - }} +
@@ -444,43 +361,6 @@ export const UserProfileTab = () => { - - - - Crop your new profile picture - -
- {profileAvatar ? ( - - ) : null} -
-
- - -
-
-
); };