FIX: Integration of Welcome dialog

This commit is contained in:
Nicolás Hatcher
2025-09-25 20:57:57 +02:00
committed by Nicolás Hatcher Andrés
parent 2496227344
commit 6a3e37f4c1
3 changed files with 61 additions and 18 deletions

View File

@@ -11,6 +11,7 @@ import {
import { import {
createNewModel, createNewModel,
deleteSelectedModel, deleteSelectedModel,
isStorageEmpty,
loadModelFromStorageOrCreate, loadModelFromStorageOrCreate,
saveModelToStorage, saveModelToStorage,
saveSelectedModelInStorage, saveSelectedModelInStorage,
@@ -22,7 +23,7 @@ import { IronCalc, IronCalcIcon, Model, init } from "@ironcalc/workbook";
function App() { function App() {
const [model, setModel] = useState<Model | null>(null); const [model, setModel] = useState<Model | null>(null);
const [showWelcomeDialog, setShowWelcomeDialog] = useState(true); const [showWelcomeDialog, setShowWelcomeDialog] = useState(false);
useEffect(() => { useEffect(() => {
async function start() { async function start() {
@@ -55,7 +56,13 @@ function App() {
} else { } else {
// try to load from local storage // try to load from local storage
const newModel = loadModelFromStorageOrCreate(); const newModel = loadModelFromStorageOrCreate();
setModel(newModel); if (!newModel) {
setShowWelcomeDialog(true);
const createdModel = new Model("template", "en", "UTC");
setModel(createdModel);
} else {
setModel(newModel);
}
} }
} }
start(); start();
@@ -95,7 +102,7 @@ function App() {
setModel(newModel); setModel(newModel);
}} }}
newModel={() => { newModel={() => {
setModel(createNewModel()); setShowWelcomeDialog(true);
}} }}
setModel={(uuid: string) => { setModel={(uuid: string) => {
const newModel = selectModelFromStorage(uuid); const newModel = selectModelFromStorage(uuid);
@@ -112,7 +119,32 @@ function App() {
/> />
<IronCalc model={model} /> <IronCalc model={model} />
{showWelcomeDialog && ( {showWelcomeDialog && (
<WelcomeDialog onClose={() => setShowWelcomeDialog(false)} /> <WelcomeDialog
onClose={() => {
if (isStorageEmpty()) {
const createdModel = createNewModel();
setModel(createdModel);
}
setShowWelcomeDialog(false);
}}
onSelectTemplate={async (templateId) => {
switch (templateId) {
case "blank": {
const createdModel = createNewModel();
setModel(createdModel);
break;
}
default: {
const model_bytes = await get_documentation_model(templateId);
const importedModel = Model.from_bytes(model_bytes);
saveModelToStorage(importedModel);
setModel(importedModel);
break;
}
}
setShowWelcomeDialog(false);
}}
/>
)} )}
</Wrapper> </Wrapper>
); );

View File

@@ -6,8 +6,9 @@ import IronCalcIcon from "./ironcalc_icon_white.svg";
function WelcomeDialog(properties: { function WelcomeDialog(properties: {
onClose: () => void; onClose: () => void;
onSelectTemplate: (templateId: string) => void;
}) { }) {
const [selectedTemplate, setSelectedTemplate] = useState<string | null>( const [selectedTemplate, setSelectedTemplate] = useState<string>(
"blank", "blank",
); );
@@ -59,21 +60,23 @@ function WelcomeDialog(properties: {
description="Estimate payments, interest, and overall cost." description="Estimate payments, interest, and overall cost."
icon={<House />} icon={<House />}
iconColor="#2F80ED" iconColor="#2F80ED"
active={selectedTemplate === "mortgage"} active={selectedTemplate === "mortgage_calculator"}
onClick={() => handleTemplateSelect("mortgage")} onClick={() => handleTemplateSelect("mortgage_calculator")}
/> />
<TemplatesListItem <TemplatesListItem
title="Travel expenses tracker" title="Travel expenses tracker"
description="Track trip costs and stay on budget." description="Track trip costs and stay on budget."
icon={<TicketsPlane />} icon={<TicketsPlane />}
iconColor="#EB5757" iconColor="#EB5757"
active={selectedTemplate === "travel"} active={selectedTemplate === "travel_expenses_tracker"}
onClick={() => handleTemplateSelect("travel")} onClick={() => handleTemplateSelect("travel_expenses_tracker")}
/> />
</TemplatesListWrapper> </TemplatesListWrapper>
</DialogContent> </DialogContent>
<DialogFooter> <DialogFooter>
<DialogFooterButton>Create workbook</DialogFooterButton> <DialogFooterButton onClick={() => properties.onSelectTemplate(selectedTemplate)}>
Create workbook
</DialogFooterButton>
</DialogFooter> </DialogFooter>
</DialogWrapper> </DialogWrapper>
); );

View File

@@ -60,7 +60,7 @@ export function createNewModel(): Model {
return model; return model;
} }
export function loadModelFromStorageOrCreate(): Model { export function loadModelFromStorageOrCreate(): Model | null {
const uuid = localStorage.getItem("selected"); const uuid = localStorage.getItem("selected");
if (uuid) { if (uuid) {
// We try to load the selected model // We try to load the selected model
@@ -68,14 +68,22 @@ export function loadModelFromStorageOrCreate(): Model {
if (modelBytesString) { if (modelBytesString) {
return Model.from_bytes(base64ToBytes(modelBytesString)); return Model.from_bytes(base64ToBytes(modelBytesString));
} }
// If it doesn't exist we create one at that uuid
const newModel = new Model("Workbook1", "en", "UTC");
localStorage.setItem("selected", uuid);
localStorage.setItem(uuid, bytesToBase64(newModel.toBytes()));
return newModel;
} }
// If there was no selected model we create a new one return null;
return createNewModel(); }
// check if storage is empty
export function isStorageEmpty(): boolean {
const modelsJson = localStorage.getItem("models");
if (!modelsJson) {
return true;
}
try {
const models = JSON.parse(modelsJson);
return Object.keys(models).length === 0;
} catch (e) {
return true;
}
} }
export function saveSelectedModelInStorage(model: Model) { export function saveSelectedModelInStorage(model: Model) {