diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index c66716069..906a15ef4 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -6,6 +6,7 @@ import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { alertContext } from "../../contexts/alertContext"; import { AuthContext } from "../../contexts/authContext"; import { darkContext } from "../../contexts/darkContext"; +import { StoreContext } from "../../contexts/storeContext"; import { TabsContext } from "../../contexts/tabsContext"; import { gradients } from "../../utils/styleUtils"; import IconComponent from "../genericIconComponent"; @@ -27,6 +28,7 @@ export default function Header(): JSX.Element { const { notificationCenter } = useContext(alertContext); const location = useLocation(); const { logout, autoLogin, isAdmin, userData } = useContext(AuthContext); + const { hasStore } = useContext(StoreContext); const { stars, gradientIndex } = useContext(darkContext); const navigate = useNavigate(); @@ -64,16 +66,18 @@ export default function Header(): JSX.Element {
Community Examples
- - - + {hasStore && ( + + + + )}
diff --git a/src/frontend/src/components/storeGuard/index.tsx b/src/frontend/src/components/storeGuard/index.tsx new file mode 100644 index 000000000..448153daa --- /dev/null +++ b/src/frontend/src/components/storeGuard/index.tsx @@ -0,0 +1,12 @@ +import { useContext } from "react"; +import { Navigate } from "react-router-dom"; +import { StoreContext } from "../../contexts/storeContext"; + +export const StoreGuard = ({ children }) => { + const { hasStore } = useContext(StoreContext); + if (!hasStore) { + return ; + } + + return children; +}; diff --git a/src/frontend/src/contexts/storeContext.tsx b/src/frontend/src/contexts/storeContext.tsx index e5f90e296..35e2dd1c2 100644 --- a/src/frontend/src/contexts/storeContext.tsx +++ b/src/frontend/src/contexts/storeContext.tsx @@ -1,4 +1,5 @@ import { createContext, useState } from "react"; +import { checkHasStore } from "../controllers/API"; import { storeContextType } from "../types/contexts/store"; import { FlowType } from "../types/flow"; @@ -6,15 +7,24 @@ import { FlowType } from "../types/flow"; const initialValue = { savedFlows: {}, setSavedFlows: () => {}, + hasStore: false, + setHasStore: () => {}, }; export const StoreContext = createContext(initialValue); export function StoreProvider({ children }) { const [savedFlows, setSavedFlows] = useState<{ [key: string]: FlowType }>({}); + const [hasStore, setHasStore] = useState(false); + + checkHasStore().then((res) => { + setHasStore(res[0].has_store); + }); return ( - + {children} ); diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 70b37489d..481f56eae 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -662,3 +662,17 @@ export async function searchComponent( throw error; } } + +export async function checkHasStore() { + try { + const res = await api.get( + `https://65384701a543859d1bb15e63.mockapi.io/Store` + ); + if (res.status === 200) { + return res.data; + } + } catch (error) { + console.log("Error:", error); + throw error; + } +} diff --git a/src/frontend/src/pages/MainPage/components/components/index.tsx b/src/frontend/src/pages/MainPage/components/components/index.tsx index 7af7a3560..da6fdabef 100644 --- a/src/frontend/src/pages/MainPage/components/components/index.tsx +++ b/src/frontend/src/pages/MainPage/components/components/index.tsx @@ -19,6 +19,7 @@ export default function ComponentsComponent() { isLoading, } = useContext(TabsContext); const { setErrorData } = useContext(alertContext); + const dropdownOptions = [ { name: "Import from JSON", @@ -69,6 +70,7 @@ export default function ComponentsComponent() { } } }; + return (
{ + setTabId(""); + }, []); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [filteredCategories, setFilteredCategories] = useState(new Set()); + const { setErrorData } = useContext(alertContext); + + useEffect(() => { + handleGetComponents(); + }, []); + + const handleGetComponents = () => { + setLoading(true); + getStoreComponents(1, 10) + .then((res) => { + setLoading(false); + setData(res); + }) + .catch((err) => { + setLoading(false); + setErrorData({ + title: "Error to get components.", + list: [err["response"]["data"]["detail"]], + }); + }); + }; + + const loadingWithApiKey = loading; + const renderComponents = !loading; + + return ( + <> + {renderComponents && ( +
+
+ {data + .filter( + (f) => + Array.from(filteredCategories).length === 0 || + filteredCategories.has(f.is_component) + ) + .map((item, idx) => ( + + ))} +
+
+ )} + + {loadingWithApiKey && ( +
Loading...
+ )} + + ); +} diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index 044f09d88..c8193f522 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -8,6 +8,7 @@ import { Button } from "../../components/ui/button"; import { Separator } from "../../components/ui/separator"; import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { alertContext } from "../../contexts/alertContext"; +import { StoreContext } from "../../contexts/storeContext"; import { TabsContext } from "../../contexts/tabsContext"; export default function HomePage(): JSX.Element { const { @@ -20,6 +21,7 @@ export default function HomePage(): JSX.Element { isLoading, } = useContext(TabsContext); const { setErrorData } = useContext(alertContext); + const { hasStore } = useContext(StoreContext); const dropdownOptions = [ { name: "Import from JSON", @@ -40,6 +42,13 @@ export default function HomePage(): JSX.Element { }, ]; + if (hasStore) { + sidebarNavItems.push({ + title: "Saved Components", + href: "/saved-components", + }); + } + // Set a null id useEffect(() => { setTabId(""); diff --git a/src/frontend/src/pages/StorePage/index.tsx b/src/frontend/src/pages/StorePage/index.tsx index e9a6ec3aa..b8ef061fd 100644 --- a/src/frontend/src/pages/StorePage/index.tsx +++ b/src/frontend/src/pages/StorePage/index.tsx @@ -1,6 +1,7 @@ import { cloneDeep } from "lodash"; import { Link, Search } from "lucide-react"; import { useContext, useEffect, useState } from "react"; +import PaginatorComponent from "../../components/PaginatorComponent"; import IconComponent from "../../components/genericIconComponent"; import Header from "../../components/headerComponent"; import { Badge } from "../../components/ui/badge"; @@ -40,6 +41,11 @@ export default function StorePage(): JSX.Element { const [errorApiKey, setErrorApiKey] = useState(false); const { setErrorData } = useContext(alertContext); const { addFlow } = useContext(TabsContext); + const [totalRowsCount, setTotalRowsCount] = useState(0); + const [size, setPageSize] = useState(10); + const [index, setPageIndex] = useState(1); + + function handleChangePagination(pageIndex: number, pageSize: number) {} useEffect(() => { handleGetComponents(); @@ -66,11 +72,15 @@ export default function StorePage(): JSX.Element { }; const handleSearch = (inputText: string) => { + setLoading(true); searchComponent(inputText).then( (res) => { + setLoading(false); setSearchData(res); }, - (error) => {} + (error) => { + setLoading(false); + } ); }; @@ -198,6 +208,15 @@ export default function StorePage(): JSX.Element { ))}
+ + { + handleChangePagination(pageIndex, pageSize); + }} + >
)} diff --git a/src/frontend/src/routes.tsx b/src/frontend/src/routes.tsx index e78e0f489..a8b9610dc 100644 --- a/src/frontend/src/routes.tsx +++ b/src/frontend/src/routes.tsx @@ -3,6 +3,7 @@ import { ProtectedAdminRoute } from "./components/authAdminGuard"; import { ProtectedRoute } from "./components/authGuard"; import { ProtectedLoginRoute } from "./components/authLoginGuard"; import { CatchAllRoute } from "./components/catchAllRoutes"; +import { StoreGuard } from "./components/storeGuard"; import AdminPage from "./pages/AdminPage"; import LoginAdminPage from "./pages/AdminPage/LoginPage"; import ApiKeysPage from "./pages/ApiKeysPage"; @@ -11,6 +12,7 @@ import FlowPage from "./pages/FlowPage"; import HomePage from "./pages/MainPage"; import ComponentsComponent from "./pages/MainPage/components/components"; import FlowsComponent from "./pages/MainPage/components/flows"; +import SavedComponents from "./pages/MainPage/components/saved-components"; import ProfileSettingsPage from "./pages/ProfileSettingsPage"; import StorePage from "./pages/StorePage"; import ViewPage from "./pages/ViewPage"; @@ -38,6 +40,14 @@ const Router = () => { > } /> } /> + + + + } + /> { path="/store" element={ - + + + } /> + void; + setHasStore: (store: boolean) => void; + hasStore: boolean; };