redo how output settings is configured
This commit is contained in:
parent
45a64326f6
commit
f51e70d701
@ -69,15 +69,11 @@ async def stream_code(websocket: WebSocket):
|
|||||||
|
|
||||||
print("Received params")
|
print("Received params")
|
||||||
|
|
||||||
# Read the output settings from the request. Fall back to default if not provided.
|
# Read the code config settings from the request. Fall back to default if not provided.
|
||||||
output_settings = {"css": "tailwind", "js": "vanilla" , "components" : "html"}
|
generated_code_config = ""
|
||||||
if params["outputSettings"] and params["outputSettings"]["css"]:
|
if "generatedCodeConfig" in params and params["generatedCodeConfig"]:
|
||||||
output_settings["css"] = params["outputSettings"]["css"]
|
generated_code_config = params["generatedCodeConfig"]
|
||||||
if params["outputSettings"] and params["outputSettings"]["js"]:
|
print(f"Generating {generated_code_config} code")
|
||||||
output_settings["js"] = params["outputSettings"]["js"]
|
|
||||||
if params["outputSettings"] and params["outputSettings"]["components"]:
|
|
||||||
output_settings["components"] = params["outputSettings"]["components"]
|
|
||||||
print("Using output settings:", output_settings)
|
|
||||||
|
|
||||||
# Get the OpenAI API key from the request. Fall back to environment variable if not provided.
|
# Get the OpenAI API key from the request. Fall back to environment variable if not provided.
|
||||||
# If neither is provided, we throw an error.
|
# If neither is provided, we throw an error.
|
||||||
@ -143,10 +139,10 @@ async def stream_code(websocket: WebSocket):
|
|||||||
|
|
||||||
if params.get("resultImage") and params["resultImage"]:
|
if params.get("resultImage") and params["resultImage"]:
|
||||||
prompt_messages = assemble_prompt(
|
prompt_messages = assemble_prompt(
|
||||||
params["image"], output_settings, params["resultImage"]
|
params["image"], generated_code_config, params["resultImage"]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
prompt_messages = assemble_prompt(params["image"], output_settings)
|
prompt_messages = assemble_prompt(params["image"], generated_code_config)
|
||||||
|
|
||||||
# Image cache for updates so that we don't have to regenerate images
|
# Image cache for updates so that we don't have to regenerate images
|
||||||
image_cache = {}
|
image_cache = {}
|
||||||
|
|||||||
@ -116,21 +116,21 @@ Generate code for a web page that looks exactly like this.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def assemble_prompt(image_data_url, output_settings: dict, result_image_data_url=None):
|
def assemble_prompt(
|
||||||
|
image_data_url, generated_code_config: str, result_image_data_url=None
|
||||||
|
):
|
||||||
# Set the system prompt based on the output settings
|
# Set the system prompt based on the output settings
|
||||||
chosen_prompt_name = "tailwind"
|
|
||||||
system_content = TAILWIND_SYSTEM_PROMPT
|
system_content = TAILWIND_SYSTEM_PROMPT
|
||||||
if output_settings["css"] == "bootstrap":
|
if generated_code_config == "html_tailwind":
|
||||||
chosen_prompt_name = "bootstrap"
|
system_content = TAILWIND_SYSTEM_PROMPT
|
||||||
system_content = BOOTSTRAP_SYSTEM_PROMPT
|
elif generated_code_config == "react_tailwind":
|
||||||
if output_settings["js"] == "react":
|
|
||||||
chosen_prompt_name = "react-tailwind"
|
|
||||||
system_content = REACT_TAILWIND_SYSTEM_PROMPT
|
system_content = REACT_TAILWIND_SYSTEM_PROMPT
|
||||||
if output_settings["components"] == "ionic":
|
elif generated_code_config == "bootstrap":
|
||||||
chosen_prompt_name = "ionic-tailwind"
|
system_content = BOOTSTRAP_SYSTEM_PROMPT
|
||||||
|
elif generated_code_config == "ionic_tailwind":
|
||||||
system_content = IONIC_TAILWIND_SYSTEM_PROMPT
|
system_content = IONIC_TAILWIND_SYSTEM_PROMPT
|
||||||
|
else:
|
||||||
print("Using system prompt:", chosen_prompt_name)
|
raise Exception("Code config is not one of available options")
|
||||||
|
|
||||||
user_content = [
|
user_content = [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import ImageUpload from "./components/ImageUpload";
|
import ImageUpload from "./components/ImageUpload";
|
||||||
import CodePreview from "./components/CodePreview";
|
import CodePreview from "./components/CodePreview";
|
||||||
import Preview from "./components/Preview";
|
import Preview from "./components/Preview";
|
||||||
@ -18,15 +18,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs";
|
||||||
import SettingsDialog from "./components/SettingsDialog";
|
import SettingsDialog from "./components/SettingsDialog";
|
||||||
import {
|
import { Settings, EditorTheme, AppState, GeneratedCodeConfig } from "./types";
|
||||||
Settings,
|
|
||||||
EditorTheme,
|
|
||||||
AppState,
|
|
||||||
CSSOption,
|
|
||||||
OutputSettings,
|
|
||||||
JSFrameworkOption,
|
|
||||||
UIComponentOption,
|
|
||||||
} from "./types";
|
|
||||||
import { IS_RUNNING_ON_CLOUD } from "./config";
|
import { IS_RUNNING_ON_CLOUD } from "./config";
|
||||||
import { PicoBadge } from "./components/PicoBadge";
|
import { PicoBadge } from "./components/PicoBadge";
|
||||||
import { OnboardingNote } from "./components/OnboardingNote";
|
import { OnboardingNote } from "./components/OnboardingNote";
|
||||||
@ -52,21 +44,31 @@ function App() {
|
|||||||
screenshotOneApiKey: null,
|
screenshotOneApiKey: null,
|
||||||
isImageGenerationEnabled: true,
|
isImageGenerationEnabled: true,
|
||||||
editorTheme: EditorTheme.COBALT,
|
editorTheme: EditorTheme.COBALT,
|
||||||
|
generatedCodeConfig: GeneratedCodeConfig.HTML_TAILWIND,
|
||||||
|
// Only relevant for hosted version
|
||||||
isTermOfServiceAccepted: false,
|
isTermOfServiceAccepted: false,
|
||||||
accessCode: null,
|
accessCode: null,
|
||||||
},
|
},
|
||||||
"setting"
|
"setting"
|
||||||
);
|
);
|
||||||
const [outputSettings, setOutputSettings] = useState<OutputSettings>({
|
|
||||||
css: CSSOption.TAILWIND,
|
|
||||||
components: UIComponentOption.HTML,
|
|
||||||
js: JSFrameworkOption.NO_FRAMEWORK,
|
|
||||||
});
|
|
||||||
const [shouldIncludeResultImage, setShouldIncludeResultImage] =
|
const [shouldIncludeResultImage, setShouldIncludeResultImage] =
|
||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
|
|
||||||
const wsRef = useRef<WebSocket>(null);
|
const wsRef = useRef<WebSocket>(null);
|
||||||
|
|
||||||
|
// When the user already has the settings in local storage, newly added keys
|
||||||
|
// do not get added to the settings so if it's falsy, we populate it with the default
|
||||||
|
// value
|
||||||
|
useEffect(() => {
|
||||||
|
if (!settings.generatedCodeConfig) {
|
||||||
|
setSettings((prev) => ({
|
||||||
|
...prev,
|
||||||
|
generatedCodeConfig: GeneratedCodeConfig.HTML_TAILWIND,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}, [settings.generatedCodeConfig, setSettings]);
|
||||||
|
|
||||||
const takeScreenshot = async (): Promise<string> => {
|
const takeScreenshot = async (): Promise<string> => {
|
||||||
const iframeElement = document.querySelector(
|
const iframeElement = document.querySelector(
|
||||||
"#preview-desktop"
|
"#preview-desktop"
|
||||||
@ -116,7 +118,7 @@ function App() {
|
|||||||
setAppState(AppState.CODING);
|
setAppState(AppState.CODING);
|
||||||
|
|
||||||
// Merge settings with params
|
// Merge settings with params
|
||||||
const updatedParams = { ...params, ...settings, outputSettings };
|
const updatedParams = { ...params, ...settings };
|
||||||
|
|
||||||
generateCode(
|
generateCode(
|
||||||
wsRef,
|
wsRef,
|
||||||
@ -190,8 +192,13 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<OutputSettingsSection
|
<OutputSettingsSection
|
||||||
outputSettings={outputSettings}
|
generatedCodeConfig={settings.generatedCodeConfig}
|
||||||
setOutputSettings={setOutputSettings}
|
setGeneratedCodeConfig={(config: GeneratedCodeConfig) =>
|
||||||
|
setSettings((prev) => ({
|
||||||
|
...prev,
|
||||||
|
generatedCodeConfig: config,
|
||||||
|
}))
|
||||||
|
}
|
||||||
shouldDisableUpdates={
|
shouldDisableUpdates={
|
||||||
appState === AppState.CODING || appState === AppState.CODE_READY
|
appState === AppState.CODING || appState === AppState.CODE_READY
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,324 +5,86 @@ import {
|
|||||||
SelectItem,
|
SelectItem,
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
} from "./ui/select";
|
} from "./ui/select";
|
||||||
import {
|
import { GeneratedCodeConfig } from "../types";
|
||||||
CSSOption,
|
|
||||||
UIComponentOption,
|
|
||||||
JSFrameworkOption,
|
|
||||||
OutputSettings,
|
|
||||||
} from "../types";
|
|
||||||
import { capitalize } from "../lib/utils";
|
|
||||||
import toast from "react-hot-toast";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Label } from "@radix-ui/react-label";
|
|
||||||
import { Button } from "./ui/button";
|
|
||||||
import { Popover, PopoverTrigger, PopoverContent } from "./ui/popover";
|
|
||||||
|
|
||||||
function displayCSSOption(option: CSSOption) {
|
function generateDisplayComponent(config: GeneratedCodeConfig) {
|
||||||
switch (option) {
|
switch (config) {
|
||||||
case CSSOption.TAILWIND:
|
case GeneratedCodeConfig.HTML_TAILWIND:
|
||||||
return "Tailwind";
|
|
||||||
case CSSOption.BOOTSTRAP:
|
|
||||||
return "Bootstrap";
|
|
||||||
default:
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayJSOption(option: JSFrameworkOption) {
|
|
||||||
switch (option) {
|
|
||||||
case JSFrameworkOption.REACT:
|
|
||||||
return "React";
|
|
||||||
case JSFrameworkOption.NO_FRAMEWORK:
|
|
||||||
return "No Framework";
|
|
||||||
default:
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertStringToCSSOption(option: string) {
|
|
||||||
switch (option) {
|
|
||||||
case "tailwind":
|
|
||||||
return CSSOption.TAILWIND;
|
|
||||||
case "bootstrap":
|
|
||||||
return CSSOption.BOOTSTRAP;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unknown CSS option: ${option}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateDisplayString(settings: OutputSettings) {
|
|
||||||
if (
|
|
||||||
settings.js === JSFrameworkOption.REACT &&
|
|
||||||
settings.css === CSSOption.TAILWIND
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className="text-gray-800 dark:text-white">
|
<div>
|
||||||
Generating <span className="font-bold">React</span> +{" "}
|
<span className="font-semibold">HTML</span> +{" "}
|
||||||
<span className="font-bold">Tailwind</span> code
|
<span className="font-semibold">Tailwind</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (
|
case GeneratedCodeConfig.REACT_TAILWIND:
|
||||||
settings.js === JSFrameworkOption.NO_FRAMEWORK &&
|
|
||||||
settings.css === CSSOption.TAILWIND
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className="text-gray-800 dark:text-white">
|
<div>
|
||||||
Generating <span className="font-bold">HTML</span> +{" "}
|
<span className="font-semibold">React</span> +{" "}
|
||||||
<span className="font-bold">Tailwind</span> code
|
<span className="font-semibold">Tailwind</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (
|
case GeneratedCodeConfig.BOOTSTRAP:
|
||||||
settings.js === JSFrameworkOption.NO_FRAMEWORK &&
|
|
||||||
settings.css === CSSOption.BOOTSTRAP
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className="text-gray-800 dark:text-white">
|
<div>
|
||||||
Generating <span className="font-bold">HTML</span> +{" "}
|
<span className="font-semibold">Bootstrap</span>
|
||||||
<span className="font-bold">Bootstrap</span> code
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
case GeneratedCodeConfig.IONIC_TAILWIND:
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span className="font-semibold">Ionic</span> +{" "}
|
||||||
|
<span className="font-semibold">Tailwind</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
// TODO: Should never reach this out. Error out
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
outputSettings: OutputSettings;
|
generatedCodeConfig: GeneratedCodeConfig;
|
||||||
setOutputSettings: React.Dispatch<React.SetStateAction<OutputSettings>>;
|
setGeneratedCodeConfig: (config: GeneratedCodeConfig) => void;
|
||||||
shouldDisableUpdates?: boolean;
|
shouldDisableUpdates?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function OutputSettingsSection({
|
function OutputSettingsSection({
|
||||||
outputSettings,
|
generatedCodeConfig,
|
||||||
setOutputSettings,
|
setGeneratedCodeConfig,
|
||||||
shouldDisableUpdates = false,
|
shouldDisableUpdates = false,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const onCSSValueChange = (value: string) => {
|
|
||||||
setOutputSettings((prev) => {
|
|
||||||
if (prev.js === JSFrameworkOption.REACT) {
|
|
||||||
if (value !== CSSOption.TAILWIND) {
|
|
||||||
toast.error(
|
|
||||||
'React only supports Tailwind CSS. Change JS framework to "No Framework" to use Bootstrap.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
css: CSSOption.TAILWIND,
|
|
||||||
js: JSFrameworkOption.REACT,
|
|
||||||
components: UIComponentOption.HTML,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
css: convertStringToCSSOption(value),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onJsFrameworkChange = (value: string) => {
|
|
||||||
if (value === JSFrameworkOption.REACT) {
|
|
||||||
setOutputSettings(() => ({
|
|
||||||
css: CSSOption.TAILWIND,
|
|
||||||
js: value as JSFrameworkOption,
|
|
||||||
components: UIComponentOption.HTML,
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
setOutputSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
js: value as JSFrameworkOption,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onUIComponentOptionChange = (value: string) => {
|
|
||||||
if (value === UIComponentOption.IONIC) {
|
|
||||||
setOutputSettings(() => ({
|
|
||||||
css: CSSOption.TAILWIND,
|
|
||||||
js: JSFrameworkOption.NO_FRAMEWORK,
|
|
||||||
components: value as UIComponentOption,
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
setOutputSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
components: value as UIComponentOption,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkUIComponentOptionOrDefault = (
|
|
||||||
valueItem: UIComponentOption
|
|
||||||
): UIComponentOption => {
|
|
||||||
switch (valueItem) {
|
|
||||||
case UIComponentOption.IONIC:
|
|
||||||
if (
|
|
||||||
outputSettings.js != JSFrameworkOption.NO_FRAMEWORK ||
|
|
||||||
outputSettings.css != CSSOption.TAILWIND
|
|
||||||
) {
|
|
||||||
return UIComponentOption.HTML;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valueItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkCSSOptionOrDefault = (valueItem: CSSOption): CSSOption => {
|
|
||||||
switch (valueItem) {
|
|
||||||
default:
|
|
||||||
return valueItem;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkJSFrameworkOptionOrDefault = (
|
|
||||||
valueItem: JSFrameworkOption
|
|
||||||
): JSFrameworkOption => {
|
|
||||||
switch (valueItem) {
|
|
||||||
case JSFrameworkOption.REACT:
|
|
||||||
if (outputSettings.css != CSSOption.TAILWIND) {
|
|
||||||
return JSFrameworkOption.NO_FRAMEWORK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return valueItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
checkOutputSettingsOptions();
|
|
||||||
}, [outputSettings]);
|
|
||||||
|
|
||||||
const checkOutputSettingsOptions = () => {
|
|
||||||
if (
|
|
||||||
isHiddenOption(outputSettings.css) ||
|
|
||||||
isHiddenOption(outputSettings.js) ||
|
|
||||||
isHiddenOption(outputSettings.components)
|
|
||||||
) {
|
|
||||||
setOutputSettings((prev) => {
|
|
||||||
return {
|
|
||||||
css: checkCSSOptionOrDefault(prev.css),
|
|
||||||
js: checkJSFrameworkOptionOrDefault(prev.js),
|
|
||||||
components: checkUIComponentOptionOrDefault(prev.components),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isHiddenOption = (
|
|
||||||
option: CSSOption | JSFrameworkOption | UIComponentOption
|
|
||||||
): boolean => {
|
|
||||||
if (Object.values(CSSOption).includes(option as CSSOption)) {
|
|
||||||
return checkCSSOptionOrDefault(option as CSSOption) != option;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Object.values(JSFrameworkOption).includes(option as JSFrameworkOption)
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
checkJSFrameworkOptionOrDefault(option as JSFrameworkOption) != option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Object.values(UIComponentOption).includes(option as UIComponentOption)
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
checkUIComponentOptionOrDefault(option as UIComponentOption) != option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-y-2 justify-between text-sm">
|
<div className="flex flex-col gap-y-2 justify-between text-sm">
|
||||||
{generateDisplayString(outputSettings)}{" "}
|
|
||||||
{!shouldDisableUpdates && (
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button variant="outline">Customize</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-80 text-sm">
|
|
||||||
<div className="grid gap-4">
|
|
||||||
<div className="space-y-2">
|
|
||||||
<h4 className="font-medium leading-none">Code Settings</h4>
|
|
||||||
<p className="text-muted-foreground">
|
|
||||||
Customize your code output
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="grid gap-2">
|
|
||||||
<div className="grid grid-cols-3 items-center gap-4">
|
<div className="grid grid-cols-3 items-center gap-4">
|
||||||
<Label htmlFor="output-settings-js">JS</Label>
|
<span>Generating:</span>
|
||||||
<Select
|
<Select
|
||||||
value={outputSettings.js}
|
value={generatedCodeConfig}
|
||||||
onValueChange={onJsFrameworkChange}
|
onValueChange={(value: string) =>
|
||||||
|
setGeneratedCodeConfig(value as GeneratedCodeConfig)
|
||||||
|
}
|
||||||
|
disabled={shouldDisableUpdates}
|
||||||
>
|
>
|
||||||
<SelectTrigger
|
<SelectTrigger className="col-span-2" id="output-settings-js">
|
||||||
className="col-span-2 h-8"
|
{generateDisplayComponent(generatedCodeConfig)}
|
||||||
id="output-settings-js"
|
|
||||||
>
|
|
||||||
{displayJSOption(outputSettings.js)}
|
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectItem value={JSFrameworkOption.NO_FRAMEWORK}>
|
<SelectItem value={GeneratedCodeConfig.HTML_TAILWIND}>
|
||||||
No Framework
|
{generateDisplayComponent(GeneratedCodeConfig.HTML_TAILWIND)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value={JSFrameworkOption.REACT}>
|
<SelectItem value={GeneratedCodeConfig.REACT_TAILWIND}>
|
||||||
React
|
{generateDisplayComponent(GeneratedCodeConfig.REACT_TAILWIND)}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value={GeneratedCodeConfig.BOOTSTRAP}>
|
||||||
|
{generateDisplayComponent(GeneratedCodeConfig.BOOTSTRAP)}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value={GeneratedCodeConfig.IONIC_TAILWIND}>
|
||||||
|
{generateDisplayComponent(GeneratedCodeConfig.IONIC_TAILWIND)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 items-center gap-4">
|
|
||||||
<Label htmlFor="output-settings-css">CSS</Label>
|
|
||||||
<Select
|
|
||||||
value={outputSettings.css}
|
|
||||||
onValueChange={onCSSValueChange}
|
|
||||||
>
|
|
||||||
<SelectTrigger
|
|
||||||
className="col-span-2 h-8"
|
|
||||||
id="output-settings-css"
|
|
||||||
>
|
|
||||||
{displayCSSOption(outputSettings.css)}
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectItem value={CSSOption.TAILWIND}>
|
|
||||||
Tailwind
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value={CSSOption.BOOTSTRAP}>
|
|
||||||
Bootstrap
|
|
||||||
</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-3 items-center gap-4">
|
|
||||||
<Label htmlFor="output-settings-component">Components</Label>
|
|
||||||
<Select
|
|
||||||
value={outputSettings.components}
|
|
||||||
onValueChange={onUIComponentOptionChange}
|
|
||||||
>
|
|
||||||
<SelectTrigger
|
|
||||||
id="output-settings-component"
|
|
||||||
className="col-span-2 h-8"
|
|
||||||
>
|
|
||||||
{capitalize(outputSettings.components)}
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectItem value={UIComponentOption.HTML}>
|
|
||||||
HTML
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem
|
|
||||||
value={UIComponentOption.IONIC}
|
|
||||||
disabled={isHiddenOption(UIComponentOption.IONIC)}
|
|
||||||
>
|
|
||||||
Ionic
|
|
||||||
</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,26 +3,12 @@ export enum EditorTheme {
|
|||||||
COBALT = "cobalt",
|
COBALT = "cobalt",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CSSOption {
|
// Keep in sync with backend (prompts.py)
|
||||||
TAILWIND = "tailwind",
|
export enum GeneratedCodeConfig {
|
||||||
|
HTML_TAILWIND = "html_tailwind",
|
||||||
|
REACT_TAILWIND = "react_tailwind",
|
||||||
BOOTSTRAP = "bootstrap",
|
BOOTSTRAP = "bootstrap",
|
||||||
}
|
IONIC_TAILWIND = "ionic_tailwind",
|
||||||
|
|
||||||
export enum JSFrameworkOption {
|
|
||||||
NO_FRAMEWORK = "vanilla",
|
|
||||||
REACT = "react",
|
|
||||||
VUE = "vue",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum UIComponentOption {
|
|
||||||
HTML = 'HTML',
|
|
||||||
IONIC = 'ionic'
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OutputSettings {
|
|
||||||
css: CSSOption;
|
|
||||||
js: JSFrameworkOption;
|
|
||||||
components: UIComponentOption;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Settings {
|
export interface Settings {
|
||||||
@ -31,8 +17,10 @@ export interface Settings {
|
|||||||
screenshotOneApiKey: string | null;
|
screenshotOneApiKey: string | null;
|
||||||
isImageGenerationEnabled: boolean;
|
isImageGenerationEnabled: boolean;
|
||||||
editorTheme: EditorTheme;
|
editorTheme: EditorTheme;
|
||||||
isTermOfServiceAccepted: boolean; // Only relevant for hosted version
|
generatedCodeConfig: GeneratedCodeConfig;
|
||||||
accessCode: string | null; // Only relevant for hosted version
|
// Only relevant for hosted version
|
||||||
|
isTermOfServiceAccepted: boolean;
|
||||||
|
accessCode: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AppState {
|
export enum AppState {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user