Skip to content

Commit

Permalink
👔 Add dynamic-Catalog
Browse files Browse the repository at this point in the history
  • Loading branch information
mit-27 committed May 20, 2024
1 parent 3de34e7 commit e41ac61
Show file tree
Hide file tree
Showing 4 changed files with 1,904 additions and 74 deletions.
156 changes: 156 additions & 0 deletions apps/embedded-catalog/react/src/components/PanoraDynamicCatalog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React,{useState,useEffect} from 'react'
import {findProviderByName, providersArray,categoriesVerticals,getLogoURL} from '@panora/shared';
import useOAuth from '@/hooks/useOAuth';

interface DynamicCardProp {
projectId: string;
returnUrl: string;
linkedUserId: string;
optionalApiUrl?: string,
}


type DataState = { [key: string]: string[] };

const MainCatalog = ({projectId,returnUrl,linkedUserId,optionalApiUrl} : DynamicCardProp) => {

const [selectedVertical, setselectedVertical] = useState(''); // Default to the first category
const [selectedProvider, setSelectedProvider] = useState('');
const [data,setData] = useState<DataState>({})
const [error,setError] = useState(false)

const { open, isReady } = useOAuth({
providerName: selectedProvider.toLowerCase(),
vertical: selectedVertical.toLowerCase(),
returnUrl: returnUrl,
projectId: projectId,
linkedUserId: linkedUserId,
optionalApiUrl: optionalApiUrl,
onSuccess: () => console.log('OAuth successful'),
});

useEffect(() => {

const FetchData = async () => {
try{
const res = await fetch(`http://localhost:3000/catalog-options/single?projectID=${projectId}`,{
method:'GET',
headers: {
'Content-Type': 'application/json',
}
});
if(!res.ok)
{
throw new Error("Not found")
}
const data = await res.json();
console.log(data)
setData(JSON.parse(data.selected_catalog))
setError(false)
} catch(error)
{
setError(true)
console.log(error)
}
}

if(projectId===undefined || !projectId.match('[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}'))
{
setError(true)
return;
}


FetchData();
},[projectId])


const handleWalletClick = (walletName: string) => {
console.log(`Wallet selected: ${walletName}`);
setSelectedProvider(walletName.toLowerCase());
};

const handleCategoryClick = (category: string) => {
setselectedVertical(category);
};

const onConnect = () => {
open(() => {
console.log("Auth completed!")
});
}


return (
<div className='h-screen flex items-center justify-center'>
<div className="w-[26rem] rounded-3xl bg-[#1d1d1d] text-white">
{error ? (
<>
<div>Error</div>
</>
)
:
(
<>
<div className=" flex items-center justify-center">
{/* <img src={img} width={"30px"} className="mx-3 mb-4 w-12 h-12 rounded-xl"/> */}
{/* <h5 className="mb-2 text-2xl font-semibold tracking-tight text-gray-900 dark:text-white">Select your Integration</h5> */}
</div>
<div className="p-4 max-h-[32rem] overflow-auto scrollbar-hide">
<div className="flex mb-4 outline-none flex-wrap">
{data && Object.keys(data).map((vertical) => (
<button
key={vertical}
className={`px-3 py-1 mb-2 mr-1 rounded-full text-white text-xs font-medium transition duration-150 ${selectedVertical === vertical ? 'bg-indigo-600 hover:bg-indigo-500 ' : 'bg-neutral-700 hover:bg-neutral-600'}`}
onClick={() => handleCategoryClick(vertical)}
>
{vertical}
</button>
))}
</div>
{(
<>
{selectedVertical!=='' && data && data[selectedVertical].map((provider) => (

// <button
// key={provider}
// className={`px-3 py-1 mb-2 mr-1 rounded-full text-white text-xs font-medium transition duration-150 ${selectedProvider === provider ? 'bg-indigo-600 hover:bg-indigo-500 ' : 'bg-neutral-700 hover:bg-neutral-600'}`}
// onClick={() => handleWalletClick(provider)}
// >
// {provider.substring(0,1).toUpperCase().concat(provider.substring(1,provider.length))}
// </button>

<div
key={provider}
className={`flex items-center justify-between px-4 py-2 my-2 ${selectedProvider === provider.toLowerCase() ? 'bg-indigo-600 hover:bg-indigo-500' : 'bg-neutral-900 hover:bg-neutral-800'} border-black hover:border-indigo-800 rounded-xl transition duration-150 cursor-pointer`}
onClick={() => handleWalletClick(provider)}
>
<div className="flex items-center">
<img className="w-8 h-8 rounded-lg mr-3" src={getLogoURL(provider)} alt={provider} />
<span>{provider.substring(0,1).toUpperCase().concat(provider.substring(1,provider.length))}</span>
</div>

</div>
))}

</>
)}
</div>

<div className='flex justify-center items-center m-2'>
<button
onClick={() => onConnect()}
disabled={selectedProvider==='' || selectedVertical===''}
className={`text-white ${(selectedProvider==='' || selectedVertical==='') ? "opacity-50 cursor-not-allowed" : "hover:bg-neutral-800"} bg-neutral-700 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700`}>
Click to Connect
</button>
</div>
</>
)
}
</div>
</div>
)
}

export default MainCatalog
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import useOAuth from '@/hooks/useOAuth';
import { useEffect, useState } from 'react';
import { getDescription, providersConfig } from '@panora/shared';

interface ProviderCardProp {
name: string;
vertical: string;
projectId: string;
returnUrl: string;
linkedUserId: string;
optionalApiUrl?: string,
}


const PanoraIntegrationCard = ({name, vertical, projectId, returnUrl, linkedUserId, optionalApiUrl}: ProviderCardProp) => {
const [providerClicked, setProviderClicked] = useState(false);
const [loading, setLoading] = useState(false)

//const vertical = findProviderVertical(name.toLowerCase())
//if(!projectId || !linkedUserId) return;

const { open, isReady } = useOAuth({
providerName: name.toLowerCase(),
vertical: vertical.toLowerCase(),
returnUrl: returnUrl,
projectId: projectId,
linkedUserId: linkedUserId,
optionalApiUrl: optionalApiUrl,
onSuccess: () => console.log('OAuth successful'),
});

const onWindowClose = () => {
setLoading(false);
return;
}

useEffect(() => {
if (loading && providerClicked && isReady) {
open(onWindowClose);
return;
}
}, [providerClicked, isReady, open, loading]);


const handleClick = () => {
setLoading(true);
setProviderClicked(true);
return;
};

const img = providersConfig[vertical!.toLowerCase()][name.toLowerCase()].logoPath;

return (
<div
className="max-w-sm p-6 bg-white border-[0.007em] border-gray-200 rounded-lg shadow dark:bg-zinc-800 hover:border-gray-200 transition-colors duration-200"
>
<div className=" flex items-center justify-center">
<img src={img} width={"30px"} className="mx-3 mb-4 w-12 h-12 rounded-xl"/>
<h5 className="mb-2 text-2xl font-semibold tracking-tight text-gray-900 dark:text-white">Integrate with xzx223 {name}</h5>

</div>

<p className="mb-3 font-normal text-gray-500 dark:text-gray-400">{getDescription(name.toLowerCase())}</p>
{!loading ?
<a
href="#" className="inline-flex items-center text-indigo-600 hover:underline"
onClick={handleClick}
>
Connect in one click
<svg className="w-3 h-3 ms-2.5 rtl:rotate-[270deg]" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18">
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 11v4.833A1.166 1.166 0 0 1 13.833 17H2.167A1.167 1.167 0 0 1 1 15.833V4.167A1.166 1.166 0 0 1 2.167 3h4.618m4.447-2H17v5.768M9.111 8.889l7.778-7.778"/>
</svg>
</a>

:
<>
<p className="mb-3 font-normal text-gray-500 dark:text-gray-400">Continue in {name} </p>
<div className='flex justify-center items-center'>

</div>
</>
}
</div>
)
};



export default PanoraIntegrationCard;
97 changes: 23 additions & 74 deletions apps/embedded-catalog/react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import "./global.css";
import useOAuth from '@/hooks/useOAuth';
import { useEffect, useState } from 'react';
import { getDescription, providersConfig } from '@panora/shared';
import PanoraIntegrationCard from "./components/PanoraIntegrationCard";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import PanoraDynamicCatalog from "./components/PanoraDynamicCatalog";

interface ProviderCardProp {
name: string;
Expand All @@ -12,77 +11,15 @@ interface ProviderCardProp {
linkedUserId: string;
optionalApiUrl?: string,
}
const PanoraIntegrationCard = ({name, vertical, projectId, returnUrl, linkedUserId, optionalApiUrl}: ProviderCardProp) => {
const [providerClicked, setProviderClicked] = useState(false);
const [loading, setLoading] = useState(false)

//const vertical = findProviderVertical(name.toLowerCase())
//if(!projectId || !linkedUserId) return;

const { open, isReady } = useOAuth({
providerName: name.toLowerCase(),
vertical: vertical.toLowerCase(),
returnUrl: returnUrl,
projectId: projectId,
linkedUserId: linkedUserId,
optionalApiUrl: optionalApiUrl,
onSuccess: () => console.log('OAuth successful'),
});

const onWindowClose = () => {
setLoading(false);
return;
}

useEffect(() => {
if (loading && providerClicked && isReady) {
open(onWindowClose);
return;
}
}, [providerClicked, isReady, open, loading]);


const handleClick = () => {
setLoading(true);
setProviderClicked(true);
return;
};

const img = providersConfig[vertical!.toLowerCase()][name.toLowerCase()].logoPath;

return (
<div
className="max-w-sm p-6 bg-white border-[0.007em] border-gray-200 rounded-lg shadow dark:bg-zinc-800 hover:border-gray-200 transition-colors duration-200"
>
<div className=" flex items-center justify-center">
<img src={img} width={"30px"} className="mx-3 mb-4 w-12 h-12 rounded-xl"/>
<h5 className="mb-2 text-2xl font-semibold tracking-tight text-gray-900 dark:text-white">Integrate with {name}</h5>

</div>

<p className="mb-3 font-normal text-gray-500 dark:text-gray-400">{getDescription(name.toLowerCase())}</p>
{!loading ?
<a
href="#" className="inline-flex items-center text-indigo-600 hover:underline"
onClick={handleClick}
>
Connect in one click
<svg className="w-3 h-3 ms-2.5 rtl:rotate-[270deg]" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18">
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 11v4.833A1.166 1.166 0 0 1 13.833 17H2.167A1.167 1.167 0 0 1 1 15.833V4.167A1.166 1.166 0 0 1 2.167 3h4.618m4.447-2H17v5.768M9.111 8.889l7.778-7.778"/>
</svg>
</a>

:
<>
<p className="mb-3 font-normal text-gray-500 dark:text-gray-400">Continue in {name} </p>
<div className='flex justify-center items-center'>

</div>
</>
}
</div>
)
};
interface DynamicCardProp {
// name: string;
// vertical: string;
projectId: string;
returnUrl: string;
linkedUserId: string;
optionalApiUrl?: string,
}

const PanoraProviderCard = ({name, vertical, projectId, returnUrl, linkedUserId, optionalApiUrl}: ProviderCardProp) => {
const queryClient = new QueryClient();
Expand All @@ -92,5 +29,17 @@ const PanoraProviderCard = ({name, vertical, projectId, returnUrl, linkedUserId,
</QueryClientProvider>
)
}

const PanoraDynamicCatalogCard = ({projectId,returnUrl,linkedUserId,optionalApiUrl} : DynamicCardProp) => {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<PanoraDynamicCatalog projectId={projectId} returnUrl={returnUrl} linkedUserId={linkedUserId} optionalApiUrl={optionalApiUrl} />
</QueryClientProvider>
)

}



export default PanoraProviderCard;
export {PanoraProviderCard,PanoraDynamicCatalogCard};
Loading

0 comments on commit e41ac61

Please sign in to comment.