70 lines
1.5 KiB
Vue
70 lines
1.5 KiB
Vue
<template>
|
|
<div class="public-grid-page">
|
|
<div class="grid-area">
|
|
<GridCanvas
|
|
ref="canvas"
|
|
:master-image-url="masterImageUrl"
|
|
:cell-size="cellSize"
|
|
@selection-changed="onSelectionChanged"
|
|
/>
|
|
</div>
|
|
|
|
<SelectionSidebar
|
|
:cell-count="cellCount"
|
|
:price-per-cell="pricePerCell"
|
|
@open-upload="openUpload"
|
|
/>
|
|
|
|
<UploadModal v-if="uploadOpen" :selection="selection" @close="uploadOpen = false" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue';
|
|
import GridCanvas from '@/components/GridCanvas.vue';
|
|
import SelectionSidebar from '@/components/SelectionSidebar.vue';
|
|
import UploadModal from '@/components/UploadModal.vue';
|
|
import { usePage } from '@inertiajs/vue3';
|
|
|
|
const { props } = usePage();
|
|
|
|
const masterImageUrl = ref(props.master_image_url ?? '');
|
|
const cellSize = ref(props.cell_size ?? 20);
|
|
|
|
const cellCount = ref(0);
|
|
const pricePerCell = ref(0);
|
|
const selection = ref(null);
|
|
const uploadOpen = ref(false);
|
|
|
|
onMounted(async () => {
|
|
const res = await fetch('/api/grid/price');
|
|
const json = await res.json();
|
|
pricePerCell.value = json.price_per_cell ?? 0;
|
|
});
|
|
|
|
function onSelectionChanged(sel) {
|
|
selection.value = sel;
|
|
if (!sel) {
|
|
cellCount.value = 0;
|
|
return;
|
|
}
|
|
const { w, h } = sel; // in cells
|
|
cellCount.value = w * h;
|
|
}
|
|
|
|
function openUpload() {
|
|
uploadOpen.value = true;
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.public-grid-page {
|
|
display: flex;
|
|
gap: 1rem;
|
|
}
|
|
.grid-area {
|
|
flex: 1 1 auto;
|
|
min-height: 60vh;
|
|
}
|
|
</style>
|