Skip to content

Commit

Permalink
Refactoring integrations frontend (cleanup)
Browse files Browse the repository at this point in the history
  • Loading branch information
dangtony98 committed Dec 11, 2022
1 parent 2c83404 commit 3fc6b0c
Show file tree
Hide file tree
Showing 4 changed files with 377 additions and 302 deletions.
113 changes: 113 additions & 0 deletions frontend/components/integrations/CloudIntegration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from "react";
import Image from "next/image";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCheck,
faX,
} from "@fortawesome/free-solid-svg-icons";

interface CloudIntegration {
integration: IntegrationOption;
setSelectedIntegrationOption: () => void;
integrationOptionPress: () => void;
deleteIntegrationAuth: () => void;
authorizations: any;
}

interface IntegrationOption {
name: string;
type: string;
clientId: string;
docsLink: string;
}

const CloudIntegration = ({
integration,
setSelectedIntegrationOption,
integrationOptionPress,
deleteIntegrationAuth,
authorizations
}: CloudIntegration) => {
console.log('cio', integration);
return (
<div
className={`relative ${
["Heroku"].includes(integration.name)
? "hover:bg-white/10 duration-200 cursor-pointer"
: "opacity-50"
} flex flex-row bg-white/5 h-32 rounded-md p-4 items-center`}
onClick={() => {
if (!["Heroku"].includes(integration.name)) return;
setSelectedIntegrationOption(integration);
integrationOptionPress({
integrationOption: integration
});
}}
key={integration.name}
>
<Image
src={`/images/integrations/${integration.name}.png`}
height={70}
width={70}
alt="integration logo"
/>
{integration.name.split(" ").length > 2 ? (
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-3xl ml-4 max-w-xs">
<div>{integration.name.split(" ")[0]}</div>
<div className="text-base">
{integration.name.split(" ")[1]}{" "}
{integration.name.split(" ")[2]}
</div>
</div>
) : (
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-xl ml-4 max-w-xs">
{integration.name}
</div>
)}
{["Heroku"].includes(integration.name) &&
authorizations
.map((authorization) => authorization.integration)
.includes(integration.name.toLowerCase()) && (
<div className="absolute group z-50 top-0 right-0 flex flex-row">
<div
onClick={() => {
deleteIntegrationAuth({
integrationAuthId: authorizations
.filter(
(authorization) =>
authorization.integration ==
integration.name.toLowerCase()
)
.map((authorization) => authorization._id)[0],
});
router.reload();
}}
className="cursor-pointer w-max bg-red py-0.5 px-2 rounded-b-md text-xs flex flex-row items-center opacity-0 group-hover:opacity-100 duration-200"
>
<FontAwesomeIcon
icon={faX}
className="text-xs mr-2 py-px"
/>
Revoke
</div>
<div className="w-max bg-primary py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90 group-hover:opacity-100 duration-200">
<FontAwesomeIcon
icon={faCheck}
className="text-xs mr-2"
/>
Authorized
</div>
</div>
)}
{!["Heroku"].includes(integration.name) && (
<div className="absolute group z-50 top-0 right-0 flex flex-row">
<div className="w-max bg-yellow py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90">
Coming Soon
</div>
</div>
)}
</div>
);
}

export default CloudIntegration;
37 changes: 37 additions & 0 deletions frontend/components/integrations/FrameworkIntegration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import Image from "next/image";

interface Framework {
name: string;
link: string;
image: string;
}

const FrameworkIntegration = ({
framework
}: {
framework: Framework;
}) => {
return (
<div key={framework.name}>
<a
href={framework.link}
rel="noopener"
className={`relative flex flex-row items-center justify-center bg-bunker-500 hover:bg-gradient-to-tr hover:from-sky-400 hover:to-primary duration-200 h-32 rounded-md p-0.5 items-center cursor-pointer`}
>
<div className={`font-semibold bg-bunker-500 flex flex-col items-center justify-center h-full w-full rounded-md text-gray-300 group-hover:text-gray-200 duration-200 ${framework?.name?.split(" ").length > 1 ? "text-sm px-1" : "text-xl px-2"} text-center w-full max-w-xs`}>
{framework?.image && <Image
src={`/images/integrations/${framework.image}.png`}
height={framework?.name ? 60 : 90}
width={framework?.name ? 60 : 90}
alt="integration logo"
></Image>}
{framework?.name && framework?.image && <div className="h-2"></div>}
{framework?.name && framework.name}
</div>
</a>
</div>
);
}

export default FrameworkIntegration;
140 changes: 140 additions & 0 deletions frontend/components/integrations/Integration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import {
faArrowRight,
faRotate,
faX,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
reverseEnvMapping
} from "../../public/data/frequentConstants";
import updateIntegration from "../../pages/api/integrations/updateIntegration"
import deleteIntegration from "../../pages/api/integrations/DeleteIntegration"
import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps";
import Button from "~/components/basic/buttons/Button";
import ListBox from "~/components/basic/Listbox";

interface ProjectIntegration {
app?: string;
environment: string;
integration: string;
integrationAuth: string;
isActive: Boolean;
}

const Integration = ({
projectIntegration
}: {
projectIntegration: ProjectIntegration;
}) => {
const [integrationEnvironment, setIntegrationEnvironment] = useState(
reverseEnvMapping[projectIntegration.environment]
);
const [fileState, setFileState] = useState([]);
const router = useRouter();
const [apps, setApps] = useState([]);
const [integrationApp, setIntegrationApp] = useState(
projectIntegration.app ? projectIntegration.app : apps[0]
);

useEffect(async () => {
const tempHerokuApps = await getIntegrationApps({
integrationAuthId: projectIntegration.integrationAuth,
});
const tempHerokuAppNames = tempHerokuApps.map((app) => app.name);
setApps(tempHerokuAppNames);
setIntegrationApp(
projectIntegration.app ? projectIntegration.app : tempHerokuAppNames[0]
);
}, []);

return (
<div className="flex flex-col max-w-5xl justify-center bg-white/5 p-6 rounded-md mx-6 mt-8">
<div className="relative px-4 flex flex-row items-center justify-between mb-4">
<div className="flex flex-row">
<div>
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
ENVIRONMENT
</div>
<ListBox
data={
!projectIntegration.isActive && [
"Development",
"Staging",
"Production",
]
}
selected={integrationEnvironment}
onChange={setIntegrationEnvironment}
/>
</div>
<FontAwesomeIcon
icon={faArrowRight}
className="mx-4 text-gray-400 mt-8"
/>
<div className="mr-2">
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
INTEGRATION
</div>
<div className="py-2.5 bg-white/[.07] rounded-md pl-4 pr-20 text-sm font-semibold text-gray-300">
{projectIntegration.integration.charAt(0).toUpperCase() +
projectIntegration.integration.slice(1)}
</div>
</div>
<div>
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
HEROKU APP
</div>
<ListBox
data={!projectIntegration.isActive && apps}
selected={integrationApp}
onChange={setIntegrationApp}
/>
</div>
</div>
<div className="flex flex-row mt-6">
{projectIntegration.isActive ? (
<div className="max-w-5xl flex flex-row items-center bg-white/5 p-2 rounded-md px-4">
<FontAwesomeIcon
icon={faRotate}
className="text-lg mr-2.5 text-primary animate-spin"
/>
<div className="text-gray-300 font-semibold">In Sync</div>
</div>
) : (
<Button
text="Start Integration"
onButtonPressed={async () => {
const result = await updateIntegration({
integrationId: projectIntegration._id,
environment: envMapping[integrationEnvironment],
app: integrationApp,
isActive: true
});
router.reload();
}}
color="mineshaft"
size="md"
/>
)}
<div className="opacity-50 hover:opacity-100 duration-200 ml-2">
<Button
onButtonPressed={async () => {
await deleteIntegration({
integrationId: projectIntegration._id,
});
router.reload();
}}
color="red"
size="icon-md"
icon={faX}
/>
</div>
</div>
</div>
</div>
);
};

export default Integration;
Loading

0 comments on commit 3fc6b0c

Please sign in to comment.