From 23af88ce85455773806f9640379990e1daf65b47 Mon Sep 17 00:00:00 2001 From: nael Date: Wed, 6 Dec 2023 10:57:47 +0100 Subject: [PATCH] :bug: Fixed webapp + magic link working --- apps/webapp/.env.example | 3 +- .../components/AddLinkedAccount.tsx | 8 ++-- .../connections/ConnectionTable.tsx | 11 ++++- .../components/AddConnectionButton.tsx | 20 +++++---- .../connections/components/CopyLinkInput.tsx | 45 +++++++++++++------ .../connections/components/LoadingSpinner.tsx | 18 ++++++++ .../shared/data-table-row-actions.tsx | 2 + .../src/components/shared/team-switcher.tsx | 23 +++++----- .../hooks/mutations/useMagicLinkMutation.tsx | 7 ++- apps/webapp/src/state/magicLinkStore.ts | 13 ++++++ apps/webapp/src/state/organisationStore.ts | 14 +++--- apps/webapp/src/state/projectStore.ts | 8 ++-- apps/webapp/src/utils/config.ts | 1 + ....timestamp-1701855170066-1f4c871540e0d.mjs | 17 +++++++ 14 files changed, 140 insertions(+), 50 deletions(-) create mode 100644 apps/webapp/src/components/connections/components/LoadingSpinner.tsx create mode 100644 apps/webapp/src/state/magicLinkStore.ts create mode 100644 apps/webapp/vite.config.ts.timestamp-1701855170066-1f4c871540e0d.mjs diff --git a/apps/webapp/.env.example b/apps/webapp/.env.example index b605f7462..6eac81753 100644 --- a/apps/webapp/.env.example +++ b/apps/webapp/.env.example @@ -1 +1,2 @@ -VITE_BACKEND_DOMAIN=https://api-staging.panora.dev/ #https://api-staging.panora.dev/ \ No newline at end of file +VITE_BACKEND_DOMAIN=https://api-staging.panora.dev #https://api-staging.panora.dev/ +VITE_FRONTEND_DOMAIN=http://127.0.0.1:5173 \ No newline at end of file diff --git a/apps/webapp/src/components/configuration/components/AddLinkedAccount.tsx b/apps/webapp/src/components/configuration/components/AddLinkedAccount.tsx index 1e2fb4957..6bb8ef64b 100644 --- a/apps/webapp/src/components/configuration/components/AddLinkedAccount.tsx +++ b/apps/webapp/src/components/configuration/components/AddLinkedAccount.tsx @@ -47,16 +47,16 @@ const AddLinkedAccount = () => { setShowNewLinkedUserDialog(prevState => ({ ...prevState, open })); }; - const {selectedOrganisation} = useOrganisationStore(); - const {selectedProject} = useProjectStore(); + const {idOrg} = useOrganisationStore(); + const {idProject} = useProjectStore(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); // Prevent default form submission //console.log("submitting with project "+ selectedProject.id_project); mutate({ linked_user_origin_id: linkedUserIdentifier, - alias: selectedOrganisation.id_organisation, - id_project: selectedProject.id_project + alias: idOrg, + id_project: idProject }); setShowNewLinkedUserDialog({open: false}) }; diff --git a/apps/webapp/src/components/connections/ConnectionTable.tsx b/apps/webapp/src/components/connections/ConnectionTable.tsx index d07d66784..d7763caca 100644 --- a/apps/webapp/src/components/connections/ConnectionTable.tsx +++ b/apps/webapp/src/components/connections/ConnectionTable.tsx @@ -15,10 +15,14 @@ import { DataTableLoading } from "../shared/data-table-loading"; import { useState } from "react"; import AddConnectionButton from "./components/AddConnectionButton"; import { Skeleton } from "../ui/skeleton"; +import config from "@/utils/config"; +import useMagicLinkStore from "@/state/magicLinkStore"; export default function ConnectionTable() { const { data: connections, isLoading, error } = useConnections(); const [isGenerated, setIsGenerated] = useState(false); + + const {uniqueLink} = useMagicLinkStore(); if (isLoading) { console.log("loading connections.."); @@ -78,7 +82,7 @@ export default function ConnectionTable() { - {isGenerated ? + {isGenerated ? + : diff --git a/apps/webapp/src/components/connections/components/AddConnectionButton.tsx b/apps/webapp/src/components/connections/components/AddConnectionButton.tsx index fc25f14c7..ee32112db 100644 --- a/apps/webapp/src/components/connections/components/AddConnectionButton.tsx +++ b/apps/webapp/src/components/connections/components/AddConnectionButton.tsx @@ -49,21 +49,25 @@ const AddConnectionButton = ({ setShowNewLinkedUserDialog(prevState => ({ ...prevState, open })); }; - const { mutate } = useMagicLinkMutation(); - - const {selectedOrganisation} = useOrganisationStore(); - const {selectedProject} = useProjectStore(); + const { mutate, isError, error } = useMagicLinkMutation(); + const {nameOrg} = useOrganisationStore(); + const {idProject} = useProjectStore(); + const handleGenerate = (e: React.FormEvent) => { e.preventDefault(); // Prevent default form submission mutate({ linked_user_origin_id: linkedUserIdentifier, email: linkedUserMail, - alias: selectedOrganisation.id_organisation, - id_project: selectedProject.id_project + alias: nameOrg, + id_project: idProject }); - //setUniqueLink(data); + if(isError) { + console.log(error); + } + setIsGenerated(true); + }; @@ -166,7 +170,7 @@ const AddConnectionButton = ({ - + ) diff --git a/apps/webapp/src/components/connections/components/CopyLinkInput.tsx b/apps/webapp/src/components/connections/components/CopyLinkInput.tsx index 9ba27777f..4032dbb32 100644 --- a/apps/webapp/src/components/connections/components/CopyLinkInput.tsx +++ b/apps/webapp/src/components/connections/components/CopyLinkInput.tsx @@ -1,14 +1,19 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; +import useMagicLinkStore from '@/state/magicLinkStore'; +import config from '@/utils/config'; import { useState } from 'react'; +import { LoadingSpinner } from './LoadingSpinner'; const CopyLinkInput = () => { - const [value,] = useState('https://magic-link/edfr-12h3KKHjdd-1.com'); const [copied, setCopied] = useState(false); + const {uniqueLink} = useMagicLinkStore(); + + const handleCopy = async () => { try { - await navigator.clipboard.writeText(value); + await navigator.clipboard.writeText(`${config.FRONT_DOMAIN}/uniqueLink=${uniqueLink}`); setCopied(true); setTimeout(() => setCopied(false), 2000); // Reset copied state after 2 seconds } catch (err) { @@ -18,18 +23,30 @@ const CopyLinkInput = () => { return ( <> - - + {uniqueLink !== 'https://' ? + <> + + + : +
+ +
+ } ); }; diff --git a/apps/webapp/src/components/connections/components/LoadingSpinner.tsx b/apps/webapp/src/components/connections/components/LoadingSpinner.tsx new file mode 100644 index 000000000..451998595 --- /dev/null +++ b/apps/webapp/src/components/connections/components/LoadingSpinner.tsx @@ -0,0 +1,18 @@ +import { cn } from "@/lib/utils" + +export const LoadingSpinner = ({className}: {className:string}) => { + return ( + + ) + } \ No newline at end of file diff --git a/apps/webapp/src/components/shared/data-table-row-actions.tsx b/apps/webapp/src/components/shared/data-table-row-actions.tsx index 3f3c4f3b9..0793e381e 100644 --- a/apps/webapp/src/components/shared/data-table-row-actions.tsx +++ b/apps/webapp/src/components/shared/data-table-row-actions.tsx @@ -26,6 +26,7 @@ export function DataTableRowActions({ }: DataTableRowActionsProps) { //const task = taskSchema.parse(row.original) console.log(row); + return ( @@ -41,6 +42,7 @@ export function DataTableRowActions({ Edit Make a copy Favorite + {row.id} Labels diff --git a/apps/webapp/src/components/shared/team-switcher.tsx b/apps/webapp/src/components/shared/team-switcher.tsx index c6292ff9f..a0aef4a8b 100644 --- a/apps/webapp/src/components/shared/team-switcher.tsx +++ b/apps/webapp/src/components/shared/team-switcher.tsx @@ -70,19 +70,20 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { const { data : orgs, isLoading: isloadingOrganisations } = useOrganisations(); const { data : projects, isLoading: isloadingProjects } = useProjects(); - const { selectedProject, setSelectedProject } = useProjectStore(); - const { selectedOrganisation, setSelectedOrganisation } = useOrganisationStore(); + const { idProject, setIdProject } = useProjectStore(); + const { idOrg, setIdOrg, setOrganisationName } = useOrganisationStore(); const { profile } = useProfileStore(); useEffect(()=>{ - if(projects){ - setSelectedProject(projects[0]); + if(projects){ + setIdProject(projects[0].id_project); } if(orgs){ - setSelectedOrganisation(orgs[0]); + setOrganisationName(orgs[0].name); + setIdOrg(orgs[0].id_organization); } - },[projects, orgs, setSelectedProject, setSelectedOrganisation]) + },[projects, orgs, setIdProject, setIdOrg]) const handleOpenChange = (open: boolean) => { setShowNewDialog(prevState => ({ ...prevState, open })); @@ -121,7 +122,7 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { aria-label="Select a team" className={cn("w-[250px] justify-between", className)} > - {selectedProject ? selectedProject.name : isloadingProjects ? : "No projects found"} + {projects && projects.length > 0 ? projects[0].name : isloadingProjects ? : "No projects found"} @@ -136,7 +137,7 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { { - setSelectedProject(project) + setIdProject(project.id_project) setOpen(false) }} className="text-sm" @@ -153,7 +154,7 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { 0 && idProject === project.id_project ? "opacity-100" : "opacity-0" )} @@ -175,7 +176,7 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { { - setSelectedOrganisation(orgs[0]) + setIdOrg(orgs[0].id_organization) setOpen(false) }} className="text-sm" @@ -192,7 +193,7 @@ export default function TeamSwitcher({ className }: TeamSwitcherProps) { 0 && idOrg === orgs[0].id_organization ? "opacity-100" : "opacity-0" )} diff --git a/apps/webapp/src/hooks/mutations/useMagicLinkMutation.tsx b/apps/webapp/src/hooks/mutations/useMagicLinkMutation.tsx index 1c5d0b0c5..4a0c29b40 100644 --- a/apps/webapp/src/hooks/mutations/useMagicLinkMutation.tsx +++ b/apps/webapp/src/hooks/mutations/useMagicLinkMutation.tsx @@ -1,3 +1,4 @@ +import useMagicLinkStore from '@/state/magicLinkStore'; import config from '@/utils/config'; import { useMutation } from '@tanstack/react-query'; import toast from 'react-hot-toast'; @@ -8,6 +9,7 @@ interface ILinkDto { alias: string; id_project: string; } + const useMagicLinkMutation = () => { const generateLink = async (data: ILinkDto) => { const response = await fetch(`${config.API_URL}/magic-link/create`, { @@ -24,6 +26,8 @@ const useMagicLinkMutation = () => { return response.json(); }; + const {setUniqueLink} = useMagicLinkStore(); + return useMutation({ mutationFn: generateLink, onMutate: () => { @@ -32,7 +36,8 @@ const useMagicLinkMutation = () => { onError: (error) => { toast.error(`Error: ${error.message}`); }, - onSuccess: () => { + onSuccess: (data) => { + setUniqueLink(data.id_invite_link) toast.success('Magic Link Generated successfully!'); }, onSettled: () => { diff --git a/apps/webapp/src/state/magicLinkStore.ts b/apps/webapp/src/state/magicLinkStore.ts new file mode 100644 index 000000000..f329bb74e --- /dev/null +++ b/apps/webapp/src/state/magicLinkStore.ts @@ -0,0 +1,13 @@ +import { create } from 'zustand'; + +interface MagicLinkState { + uniqueLink: string; + setUniqueLink: (link: string) => void; +} + +const useMagicLinkStore = create()((set) => ({ + uniqueLink: "https://", + setUniqueLink: (link) => set({ uniqueLink: link }), +})); + +export default useMagicLinkStore; diff --git a/apps/webapp/src/state/organisationStore.ts b/apps/webapp/src/state/organisationStore.ts index 7db72a14d..37046aa28 100644 --- a/apps/webapp/src/state/organisationStore.ts +++ b/apps/webapp/src/state/organisationStore.ts @@ -2,13 +2,17 @@ import { create } from 'zustand'; interface OrganisationState { - selectedOrganisation: any; - setSelectedOrganisation: (org: any) => void; + idOrg: string; + setIdOrg: (id: string) => void; + nameOrg: string; + setOrganisationName: (id: string) => void; } const useOrganisationStore = create()((set) => ({ - selectedOrganisation: null, - setSelectedOrganisation: (org) => set({ selectedOrganisation: org }), -})); + idOrg: '000', + setIdOrg: (id) => set({ idOrg: id }), + nameOrg: 'org', + setOrganisationName: (name) => set({ nameOrg: name }) +})) export default useOrganisationStore; diff --git a/apps/webapp/src/state/projectStore.ts b/apps/webapp/src/state/projectStore.ts index 7027c8e79..c2bd0837e 100644 --- a/apps/webapp/src/state/projectStore.ts +++ b/apps/webapp/src/state/projectStore.ts @@ -2,13 +2,13 @@ import { create } from 'zustand'; interface ProjectState { - selectedProject: any; - setSelectedProject: (project: any) => void; + idProject: string; + setIdProject: (id: string) => void; } const useProjectStore = create()((set) => ({ - selectedProject: null, - setSelectedProject: (project) => set({ selectedProject: project }), + idProject: "123", + setIdProject: (id) => set({ idProject: id }), })); export default useProjectStore; diff --git a/apps/webapp/src/utils/config.ts b/apps/webapp/src/utils/config.ts index 32cb9c4cc..227921932 100644 --- a/apps/webapp/src/utils/config.ts +++ b/apps/webapp/src/utils/config.ts @@ -1,5 +1,6 @@ const config = { API_URL: import.meta.env.VITE_BACKEND_DOMAIN, + FRONT_DOMAIN: import.meta.env.VITE_FRONTEND_DOMAIN, }; export default config; diff --git a/apps/webapp/vite.config.ts.timestamp-1701855170066-1f4c871540e0d.mjs b/apps/webapp/vite.config.ts.timestamp-1701855170066-1f4c871540e0d.mjs new file mode 100644 index 000000000..1891d084e --- /dev/null +++ b/apps/webapp/vite.config.ts.timestamp-1701855170066-1f4c871540e0d.mjs @@ -0,0 +1,17 @@ +// vite.config.ts +import { defineConfig } from "file:///Users/nael/Desktop/Panora/node_modules/.pnpm/vite@5.0.0_@types+node@20.3.1/node_modules/vite/dist/node/index.js"; +import react from "file:///Users/nael/Desktop/Panora/node_modules/.pnpm/@vitejs+plugin-react@4.2.0_vite@5.0.0/node_modules/@vitejs/plugin-react/dist/index.mjs"; +import path from "path"; +var __vite_injected_original_dirname = "/Users/nael/Desktop/Panora/apps/webapp"; +var vite_config_default = defineConfig({ + plugins: [react()], + resolve: { + alias: { + "@": path.resolve(__vite_injected_original_dirname, "./src") + } + } +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvbmFlbC9EZXNrdG9wL1Bhbm9yYS9hcHBzL3dlYmFwcFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL25hZWwvRGVza3RvcC9QYW5vcmEvYXBwcy93ZWJhcHAvdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL1VzZXJzL25hZWwvRGVza3RvcC9QYW5vcmEvYXBwcy93ZWJhcHAvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIlxuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW3JlYWN0KCldLFxuICByZXNvbHZlOiB7XG4gICAgYWxpYXM6IHtcbiAgICAgIFwiQFwiOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcIi4vc3JjXCIpLFxuICAgIH0sXG4gIH0sXG59KVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFvUyxTQUFTLG9CQUFvQjtBQUNqVSxPQUFPLFdBQVc7QUFDbEIsT0FBTyxVQUFVO0FBRmpCLElBQU0sbUNBQW1DO0FBS3pDLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFBQSxFQUNqQixTQUFTO0FBQUEsSUFDUCxPQUFPO0FBQUEsTUFDTCxLQUFLLEtBQUssUUFBUSxrQ0FBVyxPQUFPO0FBQUEsSUFDdEM7QUFBQSxFQUNGO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K