Load in improvements
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m4s

This commit is contained in:
2026-03-18 18:51:26 -05:00
parent f9a19eb4c4
commit f2dcff7b71
3 changed files with 48 additions and 33 deletions
+10 -1
View File
@@ -2,6 +2,7 @@ import type { Component } from 'solid-js';
import { A, useLocation, useNavigate } from '@solidjs/router';
import { Show } from 'solid-js';
import { authStore } from './store/authStore';
import { appStore } from './store/appStore';
interface AppContainerProps {
children?: any;
@@ -25,7 +26,15 @@ const AppContainer: Component<AppContainerProps> = (props) => {
<div class="flex justify-between h-16">
<div class="flex items-center gap-8">
<div class="flex-shrink-0 flex items-center">
<span class="font-bold text-xl text-gray-900 tracking-tight">EstiMaker</span>
<button
onClick={() => {
appStore.resetEstimate();
navigate('/');
}}
class="font-bold text-xl text-gray-900 tracking-tight hover:text-blue-600 transition-colors"
>
EstiMaker
</button>
</div>
<nav class="flex space-x-4">
<A
+1 -1
View File
@@ -64,7 +64,7 @@ const ItemExtractor: Component<ItemExtractorProps> = () => {
<Show when={mode() === 'initial'}>
<div class="flex flex-col items-center justify-center space-y-8 py-12">
<div class="text-center mb-4">
<h1 class="text-4xl font-black text-gray-900 mb-3 tracking-tight lowercase">EstiMaker</h1>
<h1 class="text-4xl font-black text-gray-900 mb-3 tracking-tight">EstiMaker</h1>
<p class="text-gray-500 text-lg">Start a new project or continue where you left off.</p>
</div>
+20 -14
View File
@@ -1,7 +1,7 @@
import type { Component } from 'solid-js';
import { createSignal, Show, For, createEffect } from 'solid-js';
import { Portal } from 'solid-js/web';
import { X, User } from 'lucide-solid';
import { X } from 'lucide-solid';
import { pb, COLLECTIONS } from '../utils/db';
import { appStore } from '../store/appStore';
import { normalizeScopes } from '../utils/scope-utils';
@@ -14,6 +14,7 @@ interface CloudLoadModalProps {
const CloudLoadModal: Component<CloudLoadModalProps> = (props) => {
const [cloudEstimates, setCloudEstimates] = createSignal<any[]>([]);
const [isCloudLoading, setIsCloudLoading] = createSignal(false);
const [loadingRecordId, setLoadingRecordId] = createSignal<string | null>(null);
createEffect(() => {
if (props.show) {
@@ -24,8 +25,10 @@ const CloudLoadModal: Component<CloudLoadModalProps> = (props) => {
const loadCloudEstimatesList = async () => {
setIsCloudLoading(true);
try {
// Optimized: Only fetch metadata fields to keep the list response small and fast
const records = await pb.collection(COLLECTIONS.ESTIMATES).getFullList({
sort: '-created'
sort: '-created',
fields: 'id,name,created,updated'
});
setCloudEstimates(records);
} catch (err) {
@@ -36,8 +39,12 @@ const CloudLoadModal: Component<CloudLoadModalProps> = (props) => {
}
};
const loadFromCloud = (record: any) => {
const data = record.items; // items holds the full JSON blob
const loadFromCloud = async (recordMetadata: any) => {
setLoadingRecordId(recordMetadata.id);
try {
// Fetch the full record with all fields (items, history) only when requested
const record = await pb.collection(COLLECTIONS.ESTIMATES).getOne(recordMetadata.id);
const data = record.items;
if (!data) return;
if (data.scopes) appStore.setScopes(normalizeScopes(data.scopes));
@@ -54,10 +61,14 @@ const CloudLoadModal: Component<CloudLoadModalProps> = (props) => {
appStore.setLatestSnapshot(record.items);
appStore.setIsLatestVersion(true);
// Also clear out the extracted CSV items so we don't accidentally switch back to the upload screen or cause conflicts
appStore.setItems([]);
props.onClose();
} catch (err) {
console.error(err);
alert('Failed to load full estimate data.');
} finally {
setLoadingRecordId(null);
}
};
return (
@@ -85,18 +96,13 @@ const CloudLoadModal: Component<CloudLoadModalProps> = (props) => {
<p class="text-[10px] text-muted-foreground font-medium uppercase tracking-wider">
{new Date(record.created).toLocaleDateString()}
</p>
<Show when={record.items?.savedBy}>
<div class="flex items-center gap-1.5 mt-1.5 grayscale opacity-70">
<User class="w-3 h-3 text-muted-foreground" />
<span class="text-[10px] font-bold text-muted-foreground uppercase tracking-tight">{record.items.savedBy}</span>
</div>
</Show>
</div>
<button
disabled={loadingRecordId() !== null}
onClick={() => loadFromCloud(record)}
class="px-4 py-2 bg-background border border-border rounded-xl text-xs font-bold shadow-sm hover:text-primary hover:border-primary/50 transition-all opacity-0 group-hover:opacity-100"
class="px-4 py-2 bg-background border border-border rounded-xl text-xs font-bold shadow-sm hover:text-primary hover:border-primary/50 transition-all opacity-0 group-hover:opacity-100 disabled:opacity-50"
>
Load
{loadingRecordId() === record.id ? 'Fetching...' : 'Load'}
</button>
</div>
)}