feat: divide page into components

This commit is contained in:
2026-02-04 10:25:24 +05:00
parent 3aa5ada9ba
commit aa5c55f95f
7 changed files with 285 additions and 299 deletions
+72
View File
@@ -0,0 +1,72 @@
<script lang="ts">
import AppHeader from "./AppHeader.svelte";
import ErrorMessage from "./ErrorMessage.svelte";
import AppContent from "./AppContent.svelte";
interface Props {
errorMessage: string | null;
uploadedImage: string | null;
texts: Array<{ id: string; text: string }>;
backgroundImage: string | null;
panels: any[];
onUploadNewImage: () => void;
onImageUpload: (image: string) => void;
onCropComplete: (croppedImage: string) => void;
onCropCancel: () => void;
onTextAdd: (text: string) => void;
onTextUpdate: (id: string, newText: string) => void;
onTextDelete: (id: string) => void;
onDownload: (panel: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
let {
errorMessage,
uploadedImage,
texts,
backgroundImage,
panels,
onUploadNewImage,
onImageUpload,
onCropComplete,
onCropCancel,
onTextAdd,
onTextUpdate,
onTextDelete,
onDownload,
onDownloadAll
}: Props = $props();
</script>
<div class="app-container">
<AppHeader onUploadNewImage={onUploadNewImage} />
<ErrorMessage {errorMessage} />
<AppContent
{uploadedImage}
{texts}
{backgroundImage}
{panels}
onImageUpload={onImageUpload}
onCropComplete={onCropComplete}
onCropCancel={onCropCancel}
onTextAdd={onTextAdd}
onTextUpdate={onTextUpdate}
onTextDelete={onTextDelete}
onUploadNewImage={onUploadNewImage}
onDownload={onDownload}
onDownloadAll={onDownloadAll}
/>
</div>
<style>
.app-container {
display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
</style>
+70
View File
@@ -0,0 +1,70 @@
<script lang="ts">
import MainSection from "./MainSection.svelte";
import Sidebar from "./Sidebar.svelte";
interface Props {
uploadedImage: string | null;
texts: Array<{ id: string; text: string }>;
backgroundImage: string | null;
panels: any[];
onImageUpload: (image: string) => void;
onCropComplete: (croppedImage: string) => void;
onCropCancel: () => void;
onTextAdd: (text: string) => void;
onTextUpdate: (id: string, newText: string) => void;
onTextDelete: (id: string) => void;
onUploadNewImage: () => void;
onDownload: (panel: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
let {
uploadedImage,
texts,
backgroundImage,
panels,
onImageUpload,
onCropComplete,
onCropCancel,
onTextAdd,
onTextUpdate,
onTextDelete,
onUploadNewImage,
onDownload,
onDownloadAll
}: Props = $props();
</script>
<div class="app-content">
<MainSection
{uploadedImage}
{texts}
onImageUpload={onImageUpload}
onCropComplete={onCropComplete}
onCropCancel={onCropCancel}
onTextAdd={onTextAdd}
onTextUpdate={onTextUpdate}
onTextDelete={onTextDelete}
/>
<Sidebar
{backgroundImage}
{panels}
onUploadNewImage={onUploadNewImage}
onDownload={onDownload}
onDownloadAll={onDownloadAll}
/>
</div>
<style>
.app-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
}
@media (max-width: 1024px) {
.app-content {
grid-template-columns: 1fr;
}
}
</style>
+24
View File
@@ -0,0 +1,24 @@
<script lang="ts">
interface Props {
message: string | null;
}
let { message }: Props = $props();
</script>
{#if message}
<div class="error-message">
{message}
</div>
{/if}
<style>
.error-message {
background: #ffebee;
color: #c62828;
padding: 1rem;
border-radius: 8px;
border: 1px solid #ffcdd2;
font-weight: 500;
}
</style>
+53
View File
@@ -0,0 +1,53 @@
<script lang="ts">
import { uiStore } from "../stores/uiStore";
import ImageManager from "./ImageManager.svelte";
import TextSection from "./TextSection.svelte";
interface Props {
uploadedImage: string | null;
texts: Array<{ id: string; text: string }>;
onImageUpload: (image: string) => void;
onCropComplete: (croppedImage: string) => void;
onCropCancel: () => void;
onTextAdd: (text: string) => void;
onTextUpdate: (id: string, newText: string) => void;
onTextDelete: (id: string) => void;
}
let {
uploadedImage,
texts,
onImageUpload,
onCropComplete,
onCropCancel,
onTextAdd,
onTextUpdate,
onTextDelete
}: Props = $props();
</script>
<div class="main-section">
<ImageManager
currentStep={$uiStore.currentStep}
{uploadedImage}
onImageUpload={onImageUpload}
onCropComplete={onCropComplete}
onCropCancel={onCropCancel}
/>
{#if $uiStore.currentStep === "text"}
<TextSection
{texts}
onTextAdd={onTextAdd}
onTextUpdate={onTextUpdate}
onTextDelete={onTextDelete}
/>
{/if}
</div>
<style>
.main-section {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<script lang="ts">
import { uiStore } from "../stores/uiStore";
import BackgroundPreview from "./BackgroundPreview.svelte";
import PanelsList from "./PanelsList.svelte";
interface Props {
backgroundImage: string | null;
panels: any[];
onUploadNewImage: () => void;
onDownload: (panel: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
let {
backgroundImage,
panels,
onUploadNewImage,
onDownload,
onDownloadAll
}: Props = $props();
</script>
<div class="sidebar">
{#if $uiStore.currentStep === "text"}
<BackgroundPreview
{backgroundImage}
onUploadNewImage={onUploadNewImage}
/>
<PanelsList
{panels}
onDownload={onDownload}
onDownloadAll={onDownloadAll}
/>
{/if}
</div>
<style>
.sidebar {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
@media (max-width: 1024px) {
.sidebar {
order: -1;
}
}
</style>