🚀 feat(chatComponent): add build trigger component to allow users to build a flow

✨ feat(chatComponent): add loading animation to build trigger component
The BuildTrigger component is added to the chatComponent to allow users to build a flow. The component is triggered by clicking on a button and sends a POST request to the server to build the flow. A loading animation is added to the component to indicate that the flow is being built. The postBuild function is added to the API controller to handle the POST request.
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-06-11 18:09:17 -03:00
commit f88b14f33d
3 changed files with 128 additions and 0 deletions

View file

@ -0,0 +1,85 @@
import { useState, useContext } from "react";
import { Transition } from "@headlessui/react";
import { Bars3CenterLeftIcon } from "@heroicons/react/24/outline";
import { Zap } from "lucide-react";
import { nodeColors } from "../../../utils";
import { PopUpContext } from "../../../contexts/popUpContext";
import ChatModal from "../../../modals/chatModal";
import { FlowType } from "../../../types/flow";
import { postBuild } from "../../../controllers/API";
import Loading from "../../../components/ui/loading";
export default function BuildTrigger({
open,
flow,
setIsBuilt,
isBuilt,
}: {
open: boolean;
flow: FlowType;
setIsBuilt: any;
isBuilt: boolean;
}) {
const [isBuilding, setIsBuilding] = useState(false);
function handleBuild(flow: FlowType) {
const minimumLoadingTime = 500; // in milliseconds
const startTime = Date.now();
setIsBuilding(true);
postBuild(flow)
.then((res) => {
console.log(res);
setIsBuilt(true);
})
.catch((err) => {
console.log(err);
setIsBuilt(false);
})
.finally(() => {
const endTime = Date.now();
const elapsedTime = endTime - startTime;
if (elapsedTime < minimumLoadingTime) {
const remainingTime = minimumLoadingTime - elapsedTime;
setTimeout(() => {
setIsBuilding(false);
}, remainingTime);
} else {
setIsBuilding(false);
}
});
}
return (
<Transition
show={!open}
appear={true}
enter="transition ease-out duration-300"
enterFrom="translate-y-96"
enterTo="translate-y-0"
leave="transition ease-in duration-300"
leaveFrom="translate-y-0"
leaveTo="translate-y-96"
>
<div className={`fixed right-4` + (isBuilt ? " bottom-20" : " bottom-4")}>
<div
className="border flex justify-center align-center py-1 px-3 w-12 h-12 rounded-full bg-gradient-to-r from-blue-700 via-blue-600 to-blue-500 dark:border-gray-600 cursor-pointer"
onClick={() => handleBuild(flow)}
>
<button>
<div className="flex gap-3 items-center">
{isBuilding ? (
// Render your loading animation here when isBuilding is true
<Loading style={{ color: "white" }} />
) : (
<Zap className="h-6 w-6" style={{ color: "white" }} />
)}
</div>
</button>
</div>
</div>
</Transition>
);
}

View file

@ -0,0 +1,39 @@
import * as React from "react";
import { SVGProps } from "react";
export const Loading = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
className="feather feather-circle"
{...props}
>
<circle cx={12} cy={12} r={10} strokeDasharray={63} strokeDashoffset={21}>
<animateTransform
attributeName="transform"
type="rotate"
from="0 12 12"
to="360 12 12"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="stroke-dashoffset"
dur="8s"
repeatCount="indefinite"
keyTimes="0; 0.5; 1"
values="-16; -47; -16"
calcMode="spline"
keySplines="0.4 0 0.2 1; 0.4 0 0.2 1"
/>
</circle>
</svg>
);
export default Loading;

View file

@ -39,3 +39,7 @@ export async function getExamples(): Promise<FlowType[]> {
return await Promise.all(contentsPromises);
}
export async function postBuild(flow: FlowType) {
return await axios.post(`/build/${flow.id}`, flow);
}