diff --git a/web/src/assets/react.svg b/web/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/web/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web/src/components/external-ui/checkbox.tsx b/web/src/components/external-ui/checkbox.tsx deleted file mode 100644 index 2a27c2ff..00000000 --- a/web/src/components/external-ui/checkbox.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Checkbox as ChakraCheckbox } from "@chakra-ui/react" -import * as React from "react" - -export interface CheckboxProps extends ChakraCheckbox.RootProps { - icon?: React.ReactNode - inputProps?: React.InputHTMLAttributes - rootRef?: React.Ref -} - -export const Checkbox = React.forwardRef( - function Checkbox(props, ref) { - const { icon, children, inputProps, rootRef, ...rest } = props - return ( - - - - {icon || } - - {children != null && ( - {children} - )} - - ) - }, -) diff --git a/web/src/components/internal-ui/CheckBox.tsx b/web/src/components/internal-ui/CheckBox.tsx index 19f571ad..57bbb316 100644 --- a/web/src/components/internal-ui/CheckBox.tsx +++ b/web/src/components/internal-ui/CheckBox.tsx @@ -1,23 +1,46 @@ import { useFormContext } from "react-hook-form"; import { HStack } from "@chakra-ui/react"; +import { CSSProperties } from "react"; export interface Checkboxprops { fieldName: string; label: string; + style?: CSSProperties; + variant?: "chunk" | "standard"; } -const CheckBox = ({ fieldName, label }: Checkboxprops) => { +const CheckBox = ({ + fieldName, + label, + style, + variant = "standard", +}: Checkboxprops) => { const { register } = useFormContext(); return ( <> - -

{label}

- + + {variant === "standard" ? ( + <> +

{label}

+ + + ) : ( +
+

{label}

+ +
+ )}
); diff --git a/web/src/components/internal-ui/Input.tsx b/web/src/components/internal-ui/Input.tsx index f765da6a..f0a8d9f6 100644 --- a/web/src/components/internal-ui/Input.tsx +++ b/web/src/components/internal-ui/Input.tsx @@ -9,6 +9,7 @@ interface Props { placeholder?: string; disabled?: boolean; style?: CSSProperties; + classname?: string; } const Input = ({ @@ -28,7 +29,7 @@ const Input = ({ fieldName === BugFixFields.BUG_DESCRIPTION; const defaultStyle = - "border border-stone-600 bg-stone-900 rounded-md flex h-auto p-4"; + "border border-stone-600 bg-stone-900 rounded-md flex h-auto p-4 placeholder-gray-600 "; const error = errors[fieldName]; return ( diff --git a/web/src/components/internal-ui/PlatformBox.tsx b/web/src/components/internal-ui/Platform.tsx similarity index 89% rename from web/src/components/internal-ui/PlatformBox.tsx rename to web/src/components/internal-ui/Platform.tsx index 1ec285ef..3d9ebcf0 100644 --- a/web/src/components/internal-ui/PlatformBox.tsx +++ b/web/src/components/internal-ui/Platform.tsx @@ -1,6 +1,6 @@ import { Button, HStack } from "@chakra-ui/react"; import { DefaultValues, FormProvider } from "react-hook-form"; -import useTerraFormHandler from "../../features/terraform/hooks"; +import useQueryGenerator from "../../hooks/useQueryGenerator"; import CheckBox, { Checkboxprops } from "./CheckBox"; import { Endpoints } from "../../features/constants"; @@ -12,7 +12,7 @@ interface PlatformProps { mapperFunction: (data: FormData) => RequestData; } -const PlatformBox = ({ +const Platform = ({ serviceName, defaultValues, endpoint, @@ -27,7 +27,7 @@ const PlatformBox = ({ status, data, isSuccess, - } = useTerraFormHandler(defaultValues, endpoint); + } = useQueryGenerator(defaultValues, endpoint); const handleFormSubmit = handleSubmit((formData) => onSubmit(mapperFunction(formData)) ); @@ -70,4 +70,4 @@ const PlatformBox = ({ ); }; -export default PlatformBox; +export default Platform; diff --git a/web/src/features/basicGen/index.tsx b/web/src/features/basicGen/index.tsx index 91077c9a..9933bff0 100644 --- a/web/src/features/basicGen/index.tsx +++ b/web/src/features/basicGen/index.tsx @@ -10,11 +10,11 @@ import { ApiRequestBasicGen, BasicGenFormData } from "../models"; import { IoSendOutline } from "react-icons/io5"; -import useFormHandler from "../../hooks/useFormHandler"; +import useAiChat from "../../hooks/useAiChat"; import { basicGenMapper } from "../../utils/mapperFunctions"; const BasicGen = () => { - const { formMethods, handleSubmit, onSubmit, request } = useFormHandler< + const { formMethods, handleSubmit, onSubmit, request } = useAiChat< BasicGenFormData, ApiRequestBasicGen >(basicGenDefaultValues); diff --git a/web/src/features/bugFix/index.tsx b/web/src/features/bugFix/index.tsx index 7637188f..9187965c 100644 --- a/web/src/features/bugFix/index.tsx +++ b/web/src/features/bugFix/index.tsx @@ -3,14 +3,14 @@ import { FormProvider } from "react-hook-form"; import { IoSendOutline } from "react-icons/io5"; import ChatBox from "../../components/internal-ui/ChatBox"; import Input from "../../components/internal-ui/Input"; -import useFormHandler from "../../hooks/useFormHandler"; +import useAiChat from "../../hooks/useAiChat"; import { bugFixMapper } from "../../utils/mapperFunctions"; import useGptStore from "../../utils/store"; import { bugFixDefaultValues, BugFixFields, Endpoints } from "../constants"; import { ApiRequestBugFix, BugFixFormData } from "../models"; const BugFix = () => { - const { request, handleSubmit, onSubmit, formMethods } = useFormHandler< + const { request, handleSubmit, onSubmit, formMethods } = useAiChat< BugFixFormData, ApiRequestBugFix >(bugFixDefaultValues); diff --git a/web/src/features/constants.ts b/web/src/features/constants.ts index 869dbaa8..965960fa 100644 --- a/web/src/features/constants.ts +++ b/web/src/features/constants.ts @@ -1,6 +1,9 @@ import { BasicGenFormData, BugFixFormData, + Environment, + HelmFormData, + InstallFormData, TerraformArgocdFormData, TerraformDockerFormData, TerraformEc2FormData, @@ -10,6 +13,7 @@ import { export enum DownloadFolders { MY_TERRAFORM = "MyTerraform", + MY_HELM = "MyHelm", } export enum TerraformServices { @@ -30,8 +34,7 @@ export enum Endpoints { POST_IAC_T_IAM = "/IaC-template/aws/iam", POST_IAC_ARGOCD = "/IaC-template/argocd", POST_IAC_HELM = "/Helm-template", - GET_DOWNLOAD_TERRAFORM = "/download-folder", - GET_DOWNLOAD_HELM = "/download-helm", + GET_DOWNLOAD = "/download-folder", GET_DIRECTORY = "/list-directory", } @@ -82,6 +85,29 @@ export enum TerraformArgocdFields { ARGOCD_CLUSTER = "argocdCluster", } +export enum EnvironmentFields { + ENVIRONMENT_NAME = "environmentName", + VALUE = "value", +} + +export enum HelmFields { + API_VERSION = "apiVersion", + NAME = "name", + IMAGE = "image", + TARGET_PORT = "targetPort", + REPLICAS = "replicas", + SIZE = "size", + ACCESS_MODES = "accessModes", + STATELESS = "stateless", + ENABLED = "enabled", + HOST = "host", +} + +export enum InstallFields { + OS = "os", + SERVICE = "service", +} + export enum UserType { USER = "user", BOT = "bot", @@ -133,3 +159,30 @@ export const terraformIamDefaultValues: TerraformIAMFormData = { iamUser: false, iamGroup: false, }; + +export const environmentDefaultValues: Environment = { + environmentName: "ENV1", + value: "Hi", +}; + +export const helmDefaultValues: HelmFormData = { + apiVersion: 2, + pods: [ + { + accessModes: "ReadWriteOnce", + enabled: false, + host: "www.example.com", + image: "nginx", + name: "web", + replicas: 1, + size: "1Gi", + stateless: false, + targetPort: 80, + }, + ], +}; + +export const installDefaultValues: InstallFormData = { + os: "", + service: "", +}; diff --git a/web/src/features/helm/constants.ts b/web/src/features/helm/constants.ts new file mode 100644 index 00000000..254c9eb1 --- /dev/null +++ b/web/src/features/helm/constants.ts @@ -0,0 +1,85 @@ +import { HelmFields } from "../constants"; +import { FieldProperties } from "./models"; + +export enum HelmGroupNames { + GENERIC_SETTINGS = "Generic settings", + PERSISTANCE = "Persistance", + ENVIRONMENT = "Environment", + INGRESS = "Ingress", +} + +export const helmFieldProperties: FieldProperties[] = [ + { + group: { + name: HelmGroupNames.GENERIC_SETTINGS, + fields: [ + { + fieldName: HelmFields.NAME, + label: "Name", + type: "input", + placeholder: "ex: web", + }, + { + fieldName: HelmFields.IMAGE, + label: "Image", + type: "input", + placeholder: "nginx", + }, + { + fieldName: HelmFields.TARGET_PORT, + label: "Target port", + type: "input", + placeholder: "80", + }, + { + fieldName: HelmFields.REPLICAS, + label: "Replicas", + type: "input", + placeholder: "1", + }, + { + fieldName: HelmFields.STATELESS, + label: "Stateless", + type: "checkbox", + }, + ], + }, + }, + { + group: { + name: HelmGroupNames.PERSISTANCE, + fields: [ + { + fieldName: HelmFields.SIZE, + label: "Size", + type: "input", + placeholder: "1Gi", + }, + { + fieldName: HelmFields.ACCESS_MODES, + label: "Access modes", + type: "input", + placeholder: "ex: ReadWriteOnce", + }, + ], + }, + }, + { + group: { + name: HelmGroupNames.INGRESS, + fields: [ + { + fieldName: HelmFields.HOST, + label: "HOST", + type: "input", + placeholder: "ex: www.example.com", + }, + { + fieldName: HelmFields.ENABLED, + label: "Enabled", + type: "checkbox", + }, + ], + }, + }, +]; diff --git a/web/src/features/helm/index.tsx b/web/src/features/helm/index.tsx new file mode 100644 index 00000000..7c0d1ad2 --- /dev/null +++ b/web/src/features/helm/index.tsx @@ -0,0 +1,211 @@ +import { FormProvider, useForm } from "react-hook-form"; +import CheckBox from "../../components/internal-ui/CheckBox"; +import Input from "../../components/internal-ui/Input"; +import { + DownloadFolders, + Endpoints, + environmentDefaultValues, + EnvironmentFields, + helmDefaultValues, + HelmFields, +} from "../constants"; +import useQueryGenerator from "../../hooks/useQueryGenerator"; +import { helmFieldProperties } from "./constants"; +import useDownload from "../../hooks/useDownload"; +import { useEffect, useState } from "react"; +import useGptStore from "../../utils/store"; +import { ApiRequestHelm, Environment, HelmFormData } from "../models"; +import { helmMapper } from "../../utils/mapperFunctions"; + +const Helm = () => { + const [formData, setFormData] = useState(); + const [pod, setPod] = useState(0); + const [environments, setEnvironments] = useState([]); + const environmentFormMethods = useForm({ + defaultValues: environmentDefaultValues, + }); + + const { formMethods, handleSubmit, isError, onSubmit, status } = + useQueryGenerator( + helmDefaultValues, + Endpoints.POST_IAC_HELM + ); + + const setGeneratorQuery = useGptStore((s) => s.setGeneratorQuery); + + const { downloadFile, downloadRef, endpoint, isSuccess } = useDownload( + DownloadFolders.MY_HELM + ); + + const handlePodsAddition = handleSubmit((submittedData) => { + setFormData((prevData) => ({ + apiVersion: prevData?.apiVersion ?? submittedData.apiVersion ?? 2, + pods: [...(prevData?.pods ?? [], submittedData.pods)], + })); + setPod((prev) => (prev !== 7 ? prev + 1 : prev + 0)); + formMethods.reset({ pods: [helmDefaultValues.pods[0]] }); + }); + + const handleAddEnvironment = environmentFormMethods.handleSubmit( + (data: Environment) => { + if (environments.length === 8) return; + setEnvironments((prevEnv) => [...prevEnv, data]); + formData && console.log(helmMapper(formData, environments)); + } + ); + + const handleFormSubmit = handleSubmit(() => { + if (formData && formMethods.formState.isSubmitted) { + onSubmit(helmMapper(formData, environments)); + } else { + console.error("Form data is invalid"); + } + }); + + useEffect(() => { + if (isSuccess) { + downloadFile(); + setGeneratorQuery(false, ""); + } + }, [endpoint, isSuccess, downloadFile, downloadRef]); + + return ( +
+ +
+
+
+ +
+
+ {/* Render form fields for the current pod */} + {helmFieldProperties.map((group, groupIndex) => ( +
+ {/* Group Container */} +
+ {/* Group Name */} +
+ {group.group.name} +
+ + {/* Group Fields */} +
+ {group.group.fields.map((field, fieldIndex) => ( +
+ {field.type === "input" ? ( + + ) : ( +
+ +
+ )} +
+ ))} +
+
+ + {/* Divider Line */} + {groupIndex < helmFieldProperties.length - 1 && ( +
+ )} +
+ ))} +
+
+
+
+ +
+
+

+ Environments +

+
+ +
+
+ +
+ +
+
+
+
+
+
+ {isSuccess && ( +

Generated Successfully

+ )} + {formData?.pods.length && !isSuccess && ( +

+ {formData.pods.length} Pod{formData.pods.length > 1 && "'s"} added +

+ )} + {formData?.pods.length === 8 && ( +

You can add up to 8 pods

+ )} + {isError &&

Operation failed

} +
+
+ + +
+
+ + +
+ ); +}; + +export default Helm; diff --git a/web/src/features/helm/models.ts b/web/src/features/helm/models.ts new file mode 100644 index 00000000..80512bf7 --- /dev/null +++ b/web/src/features/helm/models.ts @@ -0,0 +1,15 @@ +import { HelmFields } from "../constants"; + +interface Field { + fieldName: HelmFields; + label: string; + placeholder?: string; + type: string; +} + +export interface FieldProperties { + group: { + name: string; + fields: Field[]; + }; +} diff --git a/web/src/features/install/index.tsx b/web/src/features/install/index.tsx new file mode 100644 index 00000000..4cd45f30 --- /dev/null +++ b/web/src/features/install/index.tsx @@ -0,0 +1,89 @@ +import { FormProvider } from "react-hook-form"; +import { Endpoints, installDefaultValues, InstallFields } from "../constants"; +import { + ApiRequestInstall, + ApiResponseDownload, + InstallFormData, +} from "../models"; +import useQueryGenerator from "../../hooks/useQueryGenerator"; +import Input from "../../components/internal-ui/Input"; +import { useCallback, useEffect, useRef } from "react"; + +const Install = () => { + const { + formMethods, + data, + handleSubmit, + onSubmit, + isError, + isSuccess, + status, + request, + } = useQueryGenerator( + installDefaultValues, + Endpoints.POST_INSTALL + ); + + const downloadRef = useRef(null); + + const downloadFile = useCallback( + (formData: ApiRequestInstall) => { + if (downloadRef.current) { + const response = data as ApiResponseDownload; + const blob = new Blob([response.data.output], { + type: "text/x-shellscript", + }); + const url = URL.createObjectURL(blob); + downloadRef.current.href = url; + downloadRef.current.download = `Installation_${formData.os}_${formData.service}.sh`; + downloadRef.current.click(); + URL.revokeObjectURL(url); + } + }, + [isSuccess, data, downloadRef] + ); + + useEffect(() => { + if (isSuccess && data && request) { + downloadFile(request); + } + }, [request, isSuccess, data]); + + return ( + <> + +
handleSubmit(onSubmit)(e)}> +
+ + + + {isSuccess && ( +

Generated Successfully

+ )} + {isError &&

Operation failed

} +
+
+
+
+ + ); +}; +export default Install; diff --git a/web/src/features/models.ts b/web/src/features/models.ts index ae74df16..a5bb27b7 100644 --- a/web/src/features/models.ts +++ b/web/src/features/models.ts @@ -108,6 +108,63 @@ export interface ApiRequestTerraformArgocd { argocd_cluster: boolean; } +export interface Environment { + environmentName: string; + value: string; +} + +export interface HelmFormData { + apiVersion: number; + pods: Array<{ + name: string; + image: string; + targetPort: number; + replicas: number; + size: string; + accessModes: string; + stateless: boolean; + enabled: boolean; + host: string; + }>; +} + +export interface Pod { + name: string; + image: string; + target_port: number; + replicas: number; + persistance: { + size: string; + accessModes: string; + }; + environment: Array<{ + name: string; + value: string; + }>; + stateless: boolean; + ingress: { + enabled: boolean; + host: string; + }; +} + +export interface ApiRequestHelm { + api_version: number; + pods: Pod[]; +} + +export interface InstallFormData { + os: string; + service: string; +} + +export interface ApiRequestInstall { + os: string; + service: string; +} + export interface ApiResponseDownload { - detail: [{ loc: [string, 0]; msg: string; type: string }]; + data: { + output: string; + }; } diff --git a/web/src/features/terraform/components/Argocd.tsx b/web/src/features/terraform/components/Argocd.tsx index 9423825e..9b05d5f6 100644 --- a/web/src/features/terraform/components/Argocd.tsx +++ b/web/src/features/terraform/components/Argocd.tsx @@ -1,4 +1,4 @@ -import PlatformBox from "../../../components/internal-ui/PlatformBox"; +import Platform from "../../../components/internal-ui/Platform"; import useFindPlatform from "../../../hooks/useFindPlatform"; import { TerraformServices } from "../../constants"; import { @@ -12,7 +12,7 @@ const Argocd = () => { return ( <> {platform && ( - { return ( <> {platform && ( - { return ( <> {platform && ( - { return ( <> {platform && ( - { return ( <> {platform && ( - ( +const useAiChat = ( defaultValues: UseFormProps["defaultValues"] ) => { const [request, setRequest] = useState(); @@ -21,4 +21,4 @@ const useFormHandler = ( return { formMethods, request, handleSubmit, onSubmit }; }; -export default useFormHandler; +export default useAiChat; diff --git a/web/src/features/terraform/hooks.ts b/web/src/hooks/useQueryGenerator.ts similarity index 70% rename from web/src/features/terraform/hooks.ts rename to web/src/hooks/useQueryGenerator.ts index d6302e86..a2b5aa03 100644 --- a/web/src/features/terraform/hooks.ts +++ b/web/src/hooks/useQueryGenerator.ts @@ -1,11 +1,11 @@ import { useState } from "react"; import { FieldValues, useForm, UseFormProps } from "react-hook-form"; -import { Endpoints } from "../constants"; +import { Endpoints } from "../features/constants"; import { useMutation, UseMutationOptions } from "@tanstack/react-query"; -import apiClient from "../../utils/apiClient"; -import useGptStore from "../../utils/store"; +import apiClient from "../utils/apiClient"; +import useGptStore from "../utils/store"; -const useTerraFormHandler = ( +const useQueryGenerator = ( initialValues: UseFormProps["defaultValues"], endpoint: Endpoints ) => { @@ -14,7 +14,7 @@ const useTerraFormHandler = ( const formMethods = useForm({ defaultValues: initialValues }); const { handleSubmit } = formMethods; - const useTerraMutation = (options?: UseMutationOptions) => + const useGeneratorMutation = (options?: UseMutationOptions) => useMutation({ mutationFn: () => apiClient.post(endpoint, request), onSuccess: () => setGeneratorQuery(true, endpoint), @@ -22,7 +22,7 @@ const useTerraFormHandler = ( ...options, }); - const { mutate, isSuccess, isError, status, data } = useTerraMutation(); + const { mutate, isSuccess, isError, status, data } = useGeneratorMutation(); const onSubmit = (data: K) => { setRequest(data); @@ -37,8 +37,9 @@ const useTerraFormHandler = ( isSuccess, isError, status, + request, data, }; }; -export default useTerraFormHandler; +export default useQueryGenerator; diff --git a/web/src/layouts/Header.tsx b/web/src/layouts/Header.tsx index 06a1517d..ba613d0b 100644 --- a/web/src/layouts/Header.tsx +++ b/web/src/layouts/Header.tsx @@ -5,12 +5,10 @@ const Header = () => { const setIsOpen = useGptStore((s) => s.setIsOpen); return ( <> -
+
diff --git a/web/src/router.tsx b/web/src/router.tsx index 114e4361..99e0c086 100644 --- a/web/src/router.tsx +++ b/web/src/router.tsx @@ -10,6 +10,8 @@ import EC2 from "./features/terraform/components/EC2"; import S3 from "./features/terraform/components/S3"; import IAM from "./features/terraform/components/IAM"; import Argocd from "./features/terraform/components/Argocd"; +import Helm from "./features/helm"; +import Install from "./features/install"; export const router = createBrowserRouter([ { path: "/", @@ -18,6 +20,8 @@ export const router = createBrowserRouter([ children: [ { index: true, element: }, { path: routes.bugFix, element: }, + { path: routes.helm, element: }, + { path: routes.install, element: }, { path: routes.terraformTemplate, element: , diff --git a/web/src/utils/formValidator.tsx b/web/src/utils/formValidator.tsx index fca66fa7..c1722806 100644 --- a/web/src/utils/formValidator.tsx +++ b/web/src/utils/formValidator.tsx @@ -1,5 +1,9 @@ import { RegisterOptions } from "react-hook-form"; -import { BasicGenFields, BugFixFields } from "../features/constants"; +import { + BasicGenFields, + BugFixFields, + InstallFields, +} from "../features/constants"; export const validateForm = (fieldName: string) => { let validationRules: RegisterOptions = {}; @@ -30,6 +34,8 @@ export const validateForm = (fieldName: string) => { break; case BugFixFields.VERSION: case BugFixFields.BUG_DESCRIPTION: + case InstallFields.OS: + case InstallFields.SERVICE: case BasicGenFields.INPUT: validationRules = { required: { @@ -38,6 +44,13 @@ export const validateForm = (fieldName: string) => { }, }; break; + default: + validationRules = { + required: { + value: true, + message: "Input can not be empty", + }, + }; } return validationRules; }; diff --git a/web/src/utils/mapperFunctions.ts b/web/src/utils/mapperFunctions.ts index a43033db..691456ec 100644 --- a/web/src/utils/mapperFunctions.ts +++ b/web/src/utils/mapperFunctions.ts @@ -13,6 +13,9 @@ import { ApiRequestTerraformIam, ApiRequestTerraformArgocd, TerraformArgocdFormData, + HelmFormData, + ApiRequestHelm, + Environment, } from "../features/models"; export const basicGenMapper = (data: BasicGenFormData): ApiRequestBasicGen => ({ @@ -79,3 +82,29 @@ export const terraformArgocdMapper = ( argocd_cluster: data.argocdCluster, argocd_repository: data.argocdRepository, }); + +export const helmMapper = ( + data: HelmFormData, + environments: Environment[] +): ApiRequestHelm => ({ + api_version: Number(data.apiVersion), + pods: data.pods.map((item) => ({ + environment: environments.map((env) => ({ + name: env.environmentName, + value: env.value, + })), + image: item.image, + ingress: { + enabled: item.enabled, + host: item.host, + }, + name: item.name, + persistance: { + accessModes: item.accessModes, + size: item.size, + }, + replicas: item.replicas, + stateless: item.stateless, + target_port: item.targetPort, + })), +}); diff --git a/web/src/utils/nameGenerator.ts b/web/src/utils/nameGenerator.ts index 11405a18..51546e4a 100644 --- a/web/src/utils/nameGenerator.ts +++ b/web/src/utils/nameGenerator.ts @@ -18,6 +18,8 @@ export const nameGenerator = (endpoint: Endpoints | "") => { case Endpoints.POST_IAC_ARGOCD: name = "ARGOCD"; break; + case Endpoints.POST_IAC_HELM: + name = "zip"; } return name; }; diff --git a/web/src/utils/routing.ts b/web/src/utils/routing.ts index 5f7c9c24..2e08b1cf 100644 --- a/web/src/utils/routing.ts +++ b/web/src/utils/routing.ts @@ -1,17 +1,17 @@ -import { Endpoints } from "../features/constants"; - export const routes = { basicGen: "/", bugFix: "/IaC-bugfix", terraformTemplate: "/terraform-template", + helm: "/helm", + install: "/install", }; export const btnMappings = [ { label: "Basic", route: routes.basicGen }, { label: "Bug fix", route: routes.bugFix }, { label: "Terraform template", route: routes.terraformTemplate }, - { label: "Installation", route: Endpoints.POST_INSTALL }, - { label: "Helm Template", route: Endpoints.POST_IAC_HELM }, + { label: "Helm Template", route: routes.helm }, + { label: "Installation", route: routes.install }, ]; export const terraformRoutes = { diff --git a/web/tailwind.config.js b/web/tailwind.config.js index f8cd1e3a..fc74c1be 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -4,7 +4,11 @@ import daisyui from "daisyui"; export default { content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], theme: { - extend: {}, + extend: { + boxShadow: { + "3xl": "0 35px 60px -15px rgba(0, 0, 0, 0.4)", + }, + }, }, plugins: [daisyui], }; diff --git a/web/vite.config.ts b/web/vite.config.ts index f3a302cc..17f2a9c0 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -3,13 +3,12 @@ import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig(({ mode }) => { - // Load environment variables based on the current mode const env = loadEnv(mode, process.cwd(), ""); return { plugins: [react(), tsconfigPaths()], server: { - port: Number(env.VITE_PORT) || 5173, // Use VITE_PORT from .env file or fallback + port: Number(env.VITE_PORT) || 5173, // Use VITE_PORT from .env to customize port options }, }; });