import { D as ensure_array_like, P as getContext, bt as unsubscribe_stores, dt as spread_props, f as attr, ft as store_get, g as bind_props, k as escape_html, p as attr_class, pt as stringify, w as derived, y as clsx$1 } from "./events-Bhh2w-5S.js";
import { r as goto } from "./client-bZcBshMs.js";
import { B as Separator, D as PLException, M as ProjectCache, N as ProjectLoader, V as Spinner, a as Card_content, b as Loading_button, i as Card, it as getConfig, n as Button, pt as runSafe, tt as createQuery } from "./error-DYeUQ7mQ.js";
import { c as Skeleton, l as logo_default, n as Dialog_content, s as Input, t as Dialog } from "./logo-DQI0khKS.js";
import { a as Form$1, i as string, l as useForm, n as boolean, o as FormField, r as object, t as _enum } from "./schemas-BDVbWglI.js";
//#region .svelte-kit/adapter-bun/entries/pages/_page.svelte.js
function Cache_project_list_skeleton($$renderer) {
	$$renderer.push(`<div class="flex flex-col gap-1"><!--[-->`);
	const each_array = ensure_array_like({ length: 3 });
	for (let i = 0, $$length = each_array.length; i < $$length; i++) {
		$$renderer.push(`<div class="flex items-center gap-3 px-2 py-2">`);
		Skeleton($$renderer, { class: "size-9 rounded-md shrink-0" });
		$$renderer.push(`<!----> <div class="flex flex-col gap-1.5 flex-1 min-w-0">`);
		Skeleton($$renderer, { class: "h-3.5 w-3/4" });
		$$renderer.push(`<!----> `);
		Skeleton($$renderer, { class: "h-3 w-1/2" });
		$$renderer.push(`<!----></div></div>`);
	}
	$$renderer.push(`<!--]--></div>`);
}
function Cache_project($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		const { project, disabled, isLoading, onClick, onRemove } = $$props;
		$$renderer.push(`<div class="flex items-center"><button${attr("disabled", disabled || isLoading || project.invalid, true)}${attr_class(clsx$1(["flex items-center gap-3 p-2 rounded-lg transition-colors text-left w-[calc(100%-3.25rem)]", disabled || isLoading || project.invalid ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-muted/50"]))}><img${attr("alt", `${stringify(project.name ?? "Unknown")} cover`)}${attr("src", project.imageUrl || "/_app/immutable/assets/defaultProjectCover.BHxYINJa.png")} class="size-9 rounded-md object-cover shrink-0"/> <span class="flex flex-col min-w-0"><span class="text-sm font-medium truncate">${escape_html(project.name ?? "Unknown")}</span> <span class="text-xs text-muted-foreground truncate">${escape_html(project.resolvable)}</span></span></button> <div class="h-full aspect-square">`);
		if (isLoading) {
			$$renderer.push("<!--[0-->");
			$$renderer.push(`<div class="h-full w-full flex items-center justify-center">`);
			Spinner($$renderer, { class: "text-xl" });
			$$renderer.push(`<!----></div>`);
		} else {
			$$renderer.push("<!--[-1-->");
			$$renderer.push(`<button aria-label="Remove project" title="Remove project"${attr("disabled", disabled, true)}${attr_class(clsx$1(["h-full w-full p-2 flex items-center justify-center rounded-lg transition-colors", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-muted/50"]))}><div class="i-ic-round-close text-destructive text-xl"></div></button>`);
		}
		$$renderer.push(`<!--]--></div></div>`);
	});
}
function FormFieldInput($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		var $$store_subs;
		const { name, label, type, placeholder, description, class: className, classNames } = $$props;
		const { form } = getContext("form")();
		{
			function children($$renderer, { props }) {
				Input($$renderer, spread_props([props, {
					type: type ?? "text",
					placeholder,
					class: classNames?.input,
					value: store_get($$store_subs ??= {}, "$form", form)[name] ?? "",
					oninput: (e) => form.update((v) => ({
						...v,
						[name]: e.currentTarget.value
					}))
				}]));
			}
			FormField($$renderer, {
				name,
				label,
				class: className,
				classNames,
				description,
				children,
				$$slots: { default: true }
			});
		}
		if ($$store_subs) unsubscribe_stores($$store_subs);
	});
}
function Create_project_form($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		var $$store_subs;
		let { onClose } = $$props;
		const formCtx = useForm({
			schema: object({
				projectName: string().min(1, "Project name is required").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
				projectPath: string().optional(),
				packageManager: _enum([
					"npm",
					"yarn",
					"pnpm",
					"bun"
				]).default("pnpm"),
				language: _enum(["ts", "js"]).default("ts"),
				multiplayerServer: boolean().default(false),
				dockerContainerization: boolean().default(false),
				createGitRepository: boolean().default(false),
				gitRemote: string().optional()
			}),
			defaultValues: {
				projectName: "",
				projectPath: "",
				packageManager: "pnpm",
				language: "ts",
				multiplayerServer: false,
				dockerContainerization: false,
				createGitRepository: false,
				gitRemote: ""
			},
			onSubmit: newProject
		});
		const { form, submitting } = formCtx;
		async function newProject(values) {
			await runSafe("create project", async () => {
				await goto(`/dashboard?id=${(await ProjectLoader.create(values)).id}`);
			});
		}
		derived(() => {
			const name = store_get($$store_subs ??= {}, "$form", form)["projectName"] || "<project-name>";
			let path = store_get($$store_subs ??= {}, "$form", form)["projectPath"] || "";
			if (!path.startsWith("/")) {
				if (!path.startsWith("./") && !path.startsWith("../")) path = `./${path}`;
			}
			if (!path.endsWith("/")) path = `${path}/`;
			return `${path}${name}`;
		});
		Form$1($$renderer, {
			form: formCtx,
			class: "w-full",
			children: ($$renderer) => {
				$$renderer.push(`<div class="modal-header"><div class="modal-icon-badge"><span class="i-ic-baseline-add text-primary text-lg"></span></div> <div><h2 class="text-sm font-semibold text-foreground tracking-tight leading-tight">Create project</h2> <p class="text-xs text-muted-foreground mt-0.5">Scaffold a new workspace</p></div></div> <div class="modal-divider"></div> <div class="modal-body">`);
				FormFieldInput($$renderer, {
					name: "projectName",
					label: "Project name",
					placeholder: "nanoforge-app"
				});
				$$renderer.push(`<!----> <button type="button" class="group flex items-center gap-3 cursor-pointer w-full"><span class="flex items-center gap-1.5 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground transition-colors duration-150">Advanced <span${attr_class(clsx$1("i-ic-baseline-keyboard-arrow-down text-sm"))}></span></span></button> `);
				$$renderer.push("<!--[-1-->");
				$$renderer.push(`<!--]--></div> <div class="modal-footer">`);
				Button($$renderer, {
					type: "button",
					variant: "ghost",
					onclick: onClose,
					class: "btn-ghost",
					children: ($$renderer) => {
						$$renderer.push(`<!---->Cancel`);
					},
					$$slots: { default: true }
				});
				$$renderer.push(`<!----> `);
				Loading_button($$renderer, {
					type: "submit",
					loading: store_get($$store_subs ??= {}, "$submitting", submitting),
					class: "btn-primary",
					children: ($$renderer) => {
						$$renderer.push(`<!---->Create project`);
					},
					$$slots: { default: true }
				});
				$$renderer.push(`<!----></div>`);
			},
			$$slots: { default: true }
		});
		if ($$store_subs) unsubscribe_stores($$store_subs);
	});
}
function Create_project_dialog($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		let { open = void 0 } = $$props;
		const onClose = () => {
			open = false;
		};
		let $$settled = true;
		let $$inner_renderer;
		function $$render_inner($$renderer) {
			if (Dialog) {
				$$renderer.push("<!--[-->");
				Dialog($$renderer, {
					get open() {
						return open;
					},
					set open($$value) {
						open = $$value;
						$$settled = false;
					},
					children: ($$renderer) => {
						if (Dialog_content) {
							$$renderer.push("<!--[-->");
							Dialog_content($$renderer, {
								showCloseButton: false,
								class: "p-0 gap-0 sm:max-w-xl w-[90vw] overflow-hidden",
								children: ($$renderer) => {
									Create_project_form($$renderer, { onClose });
								},
								$$slots: { default: true }
							});
							$$renderer.push("<!--]-->");
						} else {
							$$renderer.push("<!--[!-->");
							$$renderer.push("<!--]-->");
						}
					},
					$$slots: { default: true }
				});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
		}
		do {
			$$settled = true;
			$$inner_renderer = $$renderer.copy();
			$$render_inner($$inner_renderer);
		} while (!$$settled);
		$$renderer.subsume($$inner_renderer);
		bind_props($$props, { open });
	});
}
function Header($$renderer) {
	$$renderer.push(`<header class="h-14 flex items-center px-4 border-b border-border/40"><div class="flex items-center gap-2.5"><img${attr("src", logo_default)} alt="Logo" class="h-7 w-7 rounded-full"/> <span class="font-bold">Nanoforge - Editor</span></div></header>`);
}
function Offline_project_buttons($$renderer, $$props) {
	const { handleCreateProject, handleOpenProject } = $$props;
	Button($$renderer, {
		variant: "ghost",
		size: "lg",
		class: "justify-start gap-2 w-full",
		onclick: handleCreateProject,
		children: ($$renderer) => {
			$$renderer.push(`<span class="i-ic-baseline-add"></span> Create project`);
		},
		$$slots: { default: true }
	});
	$$renderer.push(`<!----> `);
	Button($$renderer, {
		variant: "ghost",
		size: "lg",
		class: "justify-start gap-2 w-full",
		onclick: handleOpenProject,
		children: ($$renderer) => {
			$$renderer.push(`<span class="i-ic-baseline-folder-open"></span> Open project`);
		},
		$$slots: { default: true }
	});
	$$renderer.push(`<!---->`);
}
function Online_project_buttons($$renderer) {
	const basePath = "https://projects.nanoforge.eu";
	const createProjectPath = `${basePath}/dashboard/projects`;
	const openProjectPath = `${basePath}/dashboard/projects`;
	$$renderer.push(`<a${attr("href", createProjectPath)}>`);
	Button($$renderer, {
		variant: "link",
		size: "lg",
		class: "justify-start gap-2 w-full text-foreground",
		children: ($$renderer) => {
			$$renderer.push(`<span class="i-ic-baseline-open-in-new"></span> Create project`);
		},
		$$slots: { default: true }
	});
	$$renderer.push(`<!----></a> <a${attr("href", openProjectPath)}>`);
	Button($$renderer, {
		variant: "link",
		size: "lg",
		class: "justify-start gap-2 w-full text-foreground",
		children: ($$renderer) => {
			$$renderer.push(`<span class="i-ic-baseline-open-in-new"></span> Open project`);
		},
		$$slots: { default: true }
	});
	$$renderer.push(`<!----></a>`);
}
function Open_project_form($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		var $$store_subs;
		let { onClose } = $$props;
		const formCtx = useForm({
			schema: object({ path: string().min(1, "Path is required") }),
			defaultValues: { path: "" },
			onSubmit: openProject
		});
		const { form, submitting } = formCtx;
		async function openProject(values) {
			await runSafe("open project", async () => {
				await goto(`/dashboard?id=${(await ProjectLoader.loadFromPath(values.path)).id}`);
			});
		}
		const projectPath = derived(() => {
			let path = store_get($$store_subs ??= {}, "$form", form)["path"] || "";
			if (!path.startsWith("/")) {
				if (!path.startsWith("./") && !path.startsWith("../")) path = `./${path}`;
			}
			return path;
		});
		Form$1($$renderer, {
			form: formCtx,
			class: "w-full",
			children: ($$renderer) => {
				$$renderer.push(`<div class="modal-header"><div class="modal-icon-badge"><span class="i-ic-baseline-folder-open text-primary text-lg"></span></div> <div><h2 class="text-sm font-semibold text-foreground tracking-tight leading-tight">Open project</h2> <p class="text-xs text-muted-foreground mt-0.5">Open a project</p></div></div> <div class="modal-divider"></div> <div class="modal-body">`);
				FormFieldInput($$renderer, {
					name: "path",
					label: "Project path",
					placeholder: "/home/user/project",
					description: `The path will be '${projectPath()}'`
				});
				$$renderer.push(`<!----></div> <div class="modal-footer">`);
				Button($$renderer, {
					type: "button",
					variant: "ghost",
					onclick: onClose,
					class: "btn-ghost",
					children: ($$renderer) => {
						$$renderer.push(`<!---->Cancel`);
					},
					$$slots: { default: true }
				});
				$$renderer.push(`<!----> `);
				Loading_button($$renderer, {
					type: "submit",
					loading: store_get($$store_subs ??= {}, "$submitting", submitting),
					class: "btn-primary",
					children: ($$renderer) => {
						$$renderer.push(`<!---->Open project`);
					},
					$$slots: { default: true }
				});
				$$renderer.push(`<!----></div>`);
			},
			$$slots: { default: true }
		});
		if ($$store_subs) unsubscribe_stores($$store_subs);
	});
}
function Open_project_dialog($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		let { open = void 0 } = $$props;
		const onClose = () => {
			open = false;
		};
		let $$settled = true;
		let $$inner_renderer;
		function $$render_inner($$renderer) {
			if (Dialog) {
				$$renderer.push("<!--[-->");
				Dialog($$renderer, {
					get open() {
						return open;
					},
					set open($$value) {
						open = $$value;
						$$settled = false;
					},
					children: ($$renderer) => {
						if (Dialog_content) {
							$$renderer.push("<!--[-->");
							Dialog_content($$renderer, {
								showCloseButton: false,
								class: "p-0 gap-0 sm:max-w-xl w-[90vw] overflow-hidden",
								children: ($$renderer) => {
									Open_project_form($$renderer, { onClose });
								},
								$$slots: { default: true }
							});
							$$renderer.push("<!--]-->");
						} else {
							$$renderer.push("<!--[!-->");
							$$renderer.push("<!--]-->");
						}
					},
					$$slots: { default: true }
				});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
		}
		do {
			$$settled = true;
			$$inner_renderer = $$renderer.copy();
			$$render_inner($$inner_renderer);
		} while (!$$settled);
		$$renderer.subsume($$inner_renderer);
		bind_props($$props, { open });
	});
}
var components_default = {
	CacheProject: Cache_project,
	CacheProjectListSkeleton: Cache_project_list_skeleton,
	CreateProjectDialog: Create_project_dialog,
	CreateProjectForm: Create_project_form,
	Header,
	OfflineProjectButtons: Offline_project_buttons,
	OnlineProjectButtons: Online_project_buttons,
	OpenProjectDialog: Open_project_dialog,
	OpenProjectForm: Open_project_form
};
function _page($$renderer, $$props) {
	$$renderer.component(($$renderer) => {
		let showCreateProject = false;
		let showOpenProject = false;
		let cacheProjectLoading = null;
		const isOnline = getConfig().mode === "online";
		const cacheQuery = createQuery(() => ({
			queryKey: ["projects-cache"],
			queryFn: async () => {
				return ProjectCache.getProjects();
			}
		}));
		const handleCreateProject = () => {
			if (isOnline) return;
			showCreateProject = true;
		};
		const handleOpenProject = () => {
			if (isOnline) return;
			showOpenProject = true;
		};
		const handleCacheProject = async (cache) => {
			try {
				cacheProjectLoading = cache.id;
				await goto(`/dashboard?id=${(await ProjectLoader.loadFromCacheWithTryId(cache)).id}`);
				cacheProjectLoading = null;
			} catch (error) {
				if (error instanceof PLException) {
					await error.fb();
					return;
				}
				console.error(`Error loading project ${cache.id} (${cache.resolvable}) from cache:`, error);
				await ProjectCache.invalidateProject(cache.id);
				await cacheQuery.refetch();
				cacheProjectLoading = null;
			}
		};
		const handleCacheRemoveProject = async (cache) => {
			cacheProjectLoading = cache.id;
			await ProjectCache.removeProject(cache.id);
			await cacheQuery.refetch();
			cacheProjectLoading = null;
		};
		const handleClearCache = async () => {
			cacheProjectLoading = true;
			await ProjectCache.clearProjects();
			await cacheQuery.refetch();
			cacheProjectLoading = null;
		};
		let $$settled = true;
		let $$inner_renderer;
		function $$render_inner($$renderer) {
			if (components_default.CreateProjectDialog) {
				$$renderer.push("<!--[-->");
				components_default.CreateProjectDialog($$renderer, {
					get open() {
						return showCreateProject;
					},
					set open($$value) {
						showCreateProject = $$value;
						$$settled = false;
					}
				});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
			$$renderer.push(` `);
			if (components_default.OpenProjectDialog) {
				$$renderer.push("<!--[-->");
				components_default.OpenProjectDialog($$renderer, {
					get open() {
						return showOpenProject;
					},
					set open($$value) {
						showOpenProject = $$value;
						$$settled = false;
					}
				});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
			$$renderer.push(` <div class="min-h-screen w-full flex flex-col bg-background text-foreground text-base">`);
			if (components_default.Header) {
				$$renderer.push("<!--[-->");
				components_default.Header($$renderer, {});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
			$$renderer.push(` <main class="flex-1 flex items-center justify-center p-6">`);
			if (Card) {
				$$renderer.push("<!--[-->");
				Card($$renderer, {
					class: "w-full max-w-2xl",
					children: ($$renderer) => {
						if (Card_content) {
							$$renderer.push("<!--[-->");
							Card_content($$renderer, {
								class: "p-0 flex justify-between h-[30vh]",
								children: ($$renderer) => {
									$$renderer.push(`<div class="flex flex-col gap-2 p-5 w-8/19"><p class="text-sm text-muted-foreground px-2 mb-1">Projects</p> `);
									if (isOnline) {
										$$renderer.push("<!--[0-->");
										if (components_default.OnlineProjectButtons) {
											$$renderer.push("<!--[-->");
											components_default.OnlineProjectButtons($$renderer, {});
											$$renderer.push("<!--]-->");
										} else {
											$$renderer.push("<!--[!-->");
											$$renderer.push("<!--]-->");
										}
									} else {
										$$renderer.push("<!--[-1-->");
										if (components_default.OfflineProjectButtons) {
											$$renderer.push("<!--[-->");
											components_default.OfflineProjectButtons($$renderer, {
												handleCreateProject,
												handleOpenProject
											});
											$$renderer.push("<!--]-->");
										} else {
											$$renderer.push("<!--[!-->");
											$$renderer.push("<!--]-->");
										}
									}
									$$renderer.push(`<!--]--></div> `);
									Separator($$renderer, {
										orientation: "vertical",
										class: "h-auto self-stretch"
									});
									$$renderer.push(`<!----> <div class="p-5 flex flex-col gap-3 w-10/19 h-full"><p class="text-sm text-muted-foreground px-2 mb-1">Recent</p> `);
									if (cacheQuery.isLoading || !cacheQuery.isFetched) {
										$$renderer.push("<!--[0-->");
										if (components_default.CacheProjectListSkeleton) {
											$$renderer.push("<!--[-->");
											components_default.CacheProjectListSkeleton($$renderer, {});
											$$renderer.push("<!--]-->");
										} else {
											$$renderer.push("<!--[!-->");
											$$renderer.push("<!--]-->");
										}
									} else if (cacheQuery.data && cacheQuery.data.length > 0) {
										$$renderer.push("<!--[1-->");
										$$renderer.push(`<div class="flex flex-col gap-1"><!--[-->`);
										const each_array = ensure_array_like(cacheQuery.data);
										for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
											let project = each_array[$$index];
											if (components_default.CacheProject) {
												$$renderer.push("<!--[-->");
												components_default.CacheProject($$renderer, {
													project,
													disabled: !!cacheProjectLoading,
													isLoading: cacheProjectLoading === project.id,
													onClick: () => handleCacheProject(project),
													onRemove: () => handleCacheRemoveProject(project)
												});
												$$renderer.push("<!--]-->");
											} else {
												$$renderer.push("<!--[!-->");
												$$renderer.push("<!--]-->");
											}
										}
										$$renderer.push(`<!--]--></div> `);
										Button($$renderer, {
											type: "button",
											variant: "ghost",
											class: "text-xs text-muted-foreground/50 hover:text-muted-foreground transition-colors self-end justify-self-end",
											onclick: handleClearCache,
											children: ($$renderer) => {
												$$renderer.push(`<!---->Clear cache`);
											},
											$$slots: { default: true }
										});
										$$renderer.push(`<!---->`);
									} else {
										$$renderer.push("<!--[-1-->");
										$$renderer.push(`<div class="flex h-full items-center justify-center text-center"><p class="text-sm text-muted-foreground/50 mb-4 mr-4">No recent projects</p></div>`);
									}
									$$renderer.push(`<!--]--></div>`);
								},
								$$slots: { default: true }
							});
							$$renderer.push("<!--]-->");
						} else {
							$$renderer.push("<!--[!-->");
							$$renderer.push("<!--]-->");
						}
					},
					$$slots: { default: true }
				});
				$$renderer.push("<!--]-->");
			} else {
				$$renderer.push("<!--[!-->");
				$$renderer.push("<!--]-->");
			}
			$$renderer.push(`</main></div>`);
		}
		do {
			$$settled = true;
			$$inner_renderer = $$renderer.copy();
			$$render_inner($$inner_renderer);
		} while (!$$settled);
		$$renderer.subsume($$inner_renderer);
	});
}
//#endregion
export { _page as default };

//# sourceMappingURL=_page.svelte-Bn7BSazx.js.map