NewMemoryPopup with problems
This commit is contained in:
parent
7b0740fe0a
commit
bd6b405478
52
package-lock.json
generated
52
package-lock.json
generated
|
@ -10,7 +10,7 @@
|
|||
"dependencies": {
|
||||
"@googlemaps/js-api-loader": "^1.16.8",
|
||||
"d3": "^7.9.0",
|
||||
"firebase": "^11.8.1",
|
||||
"firebase": "^11.9.0",
|
||||
"topojson-client": "^3.1.0",
|
||||
"topojson-server": "^3.0.1"
|
||||
},
|
||||
|
@ -469,9 +469,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@firebase/ai": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.3.0.tgz",
|
||||
"integrity": "sha512-qBxJTtl9hpgZr050kVFTRADX6I0Ss6mEQyp/JEkBgKwwxixKnaRNqEDGFba4OKNL7K8E4Y7LlA/ZW6L8aCKH4A==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.0.tgz",
|
||||
"integrity": "sha512-wvF33gtU6TXb6Co8TEC1pcl4dnVstYmRE/vs9XjUGE7he7Sgf5TqSu+EoXk/fuzhw5tKr1LC5eG9KdYFM+eosw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/app-check-interop-types": "0.3.3",
|
||||
|
@ -527,9 +527,9 @@
|
|||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@firebase/app": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.0.tgz",
|
||||
"integrity": "sha512-Vj3MST245nq+V5UmmfEkB3isIgPouyUr8yGJlFeL9Trg/umG5ogAvrjAYvQ8gV7daKDoQSRnJKWI2JFpQqRsuQ==",
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.1.tgz",
|
||||
"integrity": "sha512-0O33PKrXLoIWkoOO5ByFaLjZehBctSYWnb+xJkIdx2SKP/K9l1UPFXPwASyrOIqyY3ws+7orF/1j7wI5EKzPYQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/component": "0.6.17",
|
||||
|
@ -593,12 +593,12 @@
|
|||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@firebase/app-compat": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.0.tgz",
|
||||
"integrity": "sha512-LjLUrzbUgTa/sCtPoLKT2C7KShvLVHS3crnU1Du02YxnGVLE0CUBGY/NxgfR/Zg84mEbj1q08/dgesojxjn0dA==",
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.1.tgz",
|
||||
"integrity": "sha512-9VGjnY23Gc1XryoF/ABWtZVJYnaPOnjHM7dsqq9YALgKRtxI1FryvELUVkDaEIUf4In2bfkb9ZENF1S9M273Dw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/app": "0.13.0",
|
||||
"@firebase/app": "0.13.1",
|
||||
"@firebase/component": "0.6.17",
|
||||
"@firebase/logger": "0.4.4",
|
||||
"@firebase/util": "1.12.0",
|
||||
|
@ -748,9 +748,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@firebase/firestore": {
|
||||
"version": "4.7.16",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.16.tgz",
|
||||
"integrity": "sha512-5OpvlwYVUTLEnqewOlXmtIpH8t2ISlZHDW0NDbKROM2D0ATMqFkMHdvl+/wz9zOAcb8GMQYlhCihOnVAliUbpQ==",
|
||||
"version": "4.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.17.tgz",
|
||||
"integrity": "sha512-YhXWA7HlSnekExhZ5u4i0e+kpPxsh/qMrzeNDgsAva71JXK8OOuOx+yLyYBFhmu3Hr5JJDO2fsZA/wrWoQYHDg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/component": "0.6.17",
|
||||
|
@ -769,13 +769,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@firebase/firestore-compat": {
|
||||
"version": "0.3.51",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.51.tgz",
|
||||
"integrity": "sha512-E5iubPhS6aAM7oSsHMx/FGBwfA2nbEHaK/hCs+MD3l3N7rHKnq4SYCGmVu/AraSJaMndZR1I37N9A/BH7aCq5A==",
|
||||
"version": "0.3.52",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.52.tgz",
|
||||
"integrity": "sha512-nzt3Sag+EBdm1Jkw/FnnKBPk0LpUUxOlMHMADPBXYhhXrLszxn1+vb64nJsbgRIHfsCn+rg8gyGrb+8frzXrjg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/component": "0.6.17",
|
||||
"@firebase/firestore": "4.7.16",
|
||||
"@firebase/firestore": "4.7.17",
|
||||
"@firebase/firestore-types": "3.0.3",
|
||||
"@firebase/util": "1.12.0",
|
||||
"tslib": "^2.1.0"
|
||||
|
@ -2733,26 +2733,26 @@
|
|||
}
|
||||
},
|
||||
"node_modules/firebase": {
|
||||
"version": "11.8.1",
|
||||
"resolved": "https://registry.npmjs.org/firebase/-/firebase-11.8.1.tgz",
|
||||
"integrity": "sha512-oetXhPCvJZM4DVL/n/06442emMU+KzM0JLZjszpwlU6mqdFZqBwumBxn6hQkLukJyU5wsjihZHUY8HEAE2micg==",
|
||||
"version": "11.9.0",
|
||||
"resolved": "https://registry.npmjs.org/firebase/-/firebase-11.9.0.tgz",
|
||||
"integrity": "sha512-7uIGhxKtTNfDcoMKWn0G8G0Z1Zj5VeW8uzImAcUmI31PaYQdVWi2rVVig7thWB3vPianESPrLEKim2Fw7U8fiA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/ai": "1.3.0",
|
||||
"@firebase/ai": "1.4.0",
|
||||
"@firebase/analytics": "0.10.16",
|
||||
"@firebase/analytics-compat": "0.2.22",
|
||||
"@firebase/app": "0.13.0",
|
||||
"@firebase/app": "0.13.1",
|
||||
"@firebase/app-check": "0.10.0",
|
||||
"@firebase/app-check-compat": "0.3.25",
|
||||
"@firebase/app-compat": "0.4.0",
|
||||
"@firebase/app-compat": "0.4.1",
|
||||
"@firebase/app-types": "0.9.3",
|
||||
"@firebase/auth": "1.10.6",
|
||||
"@firebase/auth-compat": "0.5.26",
|
||||
"@firebase/data-connect": "0.3.9",
|
||||
"@firebase/database": "1.0.19",
|
||||
"@firebase/database-compat": "2.0.10",
|
||||
"@firebase/firestore": "4.7.16",
|
||||
"@firebase/firestore-compat": "0.3.51",
|
||||
"@firebase/firestore": "4.7.17",
|
||||
"@firebase/firestore-compat": "0.3.52",
|
||||
"@firebase/functions": "0.12.8",
|
||||
"@firebase/functions-compat": "0.3.25",
|
||||
"@firebase/installations": "0.6.17",
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"dependencies": {
|
||||
"@googlemaps/js-api-loader": "^1.16.8",
|
||||
"d3": "^7.9.0",
|
||||
"firebase": "^11.8.1",
|
||||
"firebase": "^11.9.0",
|
||||
"topojson-client": "^3.1.0",
|
||||
"topojson-server": "^3.0.1"
|
||||
}
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
<script lang="ts">
|
||||
import '../../app.css';
|
||||
import Button from './Button.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import { Loader } from '@googlemaps/js-api-loader';
|
||||
import { goto } from '$app/navigation';
|
||||
import { collection, addDoc, getFirestore, Timestamp } from 'firebase/firestore';
|
||||
import { app } from '$lib/firebase';
|
||||
|
||||
export let showPopup = false;
|
||||
<<<<<<< HEAD
|
||||
export let onAddMemory = () => {};
|
||||
=======
|
||||
export let locations: any[] = [];
|
||||
export let onAddMemory = (p0?: { location: string; images: any[]; startDate: string; endDate: string; }) => {};
|
||||
>>>>>>> 9def1973a7b39a01052b5d81f6a5327e2524e7e1
|
||||
export let onCancel = () => {};
|
||||
|
||||
let startDate = "";
|
||||
let endDate = "";
|
||||
let startDate = '';
|
||||
let endDate = '';
|
||||
let isGoogleLoaded = false;
|
||||
let dragActive = false;
|
||||
let selectedLocation = '';
|
||||
let customLocation = '';
|
||||
<<<<<<< HEAD
|
||||
let customLocationInput: HTMLInputElement;
|
||||
let images = [];
|
||||
=======
|
||||
let images: any[] = [];
|
||||
let dragActive = false;
|
||||
>>>>>>> 9def1973a7b39a01052b5d81f6a5327e2524e7e1
|
||||
let images: File[] = [];
|
||||
|
||||
let showLocationError = false;
|
||||
let showImageError = false;
|
||||
|
@ -34,20 +26,17 @@
|
|||
const GOOGLE_PLACES_API_KEY = import.meta.env.VITE_GOOGLE_PLACES_API_KEY;
|
||||
|
||||
onMount(async () => {
|
||||
if (!GOOGLE_PLACES_API_KEY) {
|
||||
console.error('Google Maps API key is missing');
|
||||
return;
|
||||
}
|
||||
if (!GOOGLE_PLACES_API_KEY) return;
|
||||
|
||||
const loader = new Loader({
|
||||
apiKey: GOOGLE_PLACES_API_KEY,
|
||||
version: "weekly",
|
||||
libraries: ["places"],
|
||||
version: 'weekly',
|
||||
libraries: ['places'],
|
||||
language: 'en'
|
||||
});
|
||||
|
||||
try {
|
||||
await loader.importLibrary("places");
|
||||
await loader.importLibrary('places');
|
||||
isGoogleLoaded = true;
|
||||
} catch (error) {
|
||||
console.error('Error loading Places Autocomplete:', error);
|
||||
|
@ -59,8 +48,7 @@
|
|||
types: ['(regions)']
|
||||
});
|
||||
|
||||
autocompleteCustom.setFields(['name', 'formatted_address']);
|
||||
|
||||
autocompleteCustom.setFields(['name']);
|
||||
autocompleteCustom.addListener('place_changed', () => {
|
||||
const place = autocompleteCustom.getPlace();
|
||||
if (place.name) {
|
||||
|
@ -70,7 +58,7 @@
|
|||
});
|
||||
}
|
||||
|
||||
function handleFiles(files: any) {
|
||||
function handleFiles(files: FileList) {
|
||||
for (const file of files) {
|
||||
if (file.type.startsWith('image/')) {
|
||||
images = [...images, file];
|
||||
|
@ -78,31 +66,56 @@
|
|||
}
|
||||
}
|
||||
|
||||
function handleDrop(event: any) {
|
||||
function handleDrop(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
dragActive = false;
|
||||
handleFiles(event.dataTransfer.files);
|
||||
handleFiles(event.dataTransfer!.files);
|
||||
}
|
||||
|
||||
function handleDragOver(event: any) {
|
||||
function handleDragOver(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
dragActive = true;
|
||||
}
|
||||
|
||||
function handleDragLeave(event: any) {
|
||||
function handleDragLeave(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
dragActive = false;
|
||||
}
|
||||
|
||||
function handleInputChange(event: any) {
|
||||
if (event.target.files) {
|
||||
handleFiles(event.target.files);
|
||||
function handleInputChange(event: Event) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
if (target.files) {
|
||||
handleFiles(target.files);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCancelClick() {
|
||||
onCancel();
|
||||
function isCustomLocation() {
|
||||
return selectedLocation === 'custom';
|
||||
}
|
||||
|
||||
function removeImage(imageToRemove: File) {
|
||||
images = images.filter(img => img !== imageToRemove);
|
||||
}
|
||||
|
||||
async function handleAddMemory() {
|
||||
showLocationError = selectedLocation === '' || (isCustomLocation() && customLocation.trim() === '');
|
||||
showImageError = images.length === 0;
|
||||
|
||||
if (showLocationError || showImageError) return;
|
||||
|
||||
const finalLocation = isCustomLocation() ? customLocation : selectedLocation;
|
||||
|
||||
const db = getFirestore(app);
|
||||
const docRef = await addDoc(collection(db, 'memories'), {
|
||||
location: finalLocation,
|
||||
startDate,
|
||||
endDate,
|
||||
images: images.map(file => URL.createObjectURL(file)), // 임시 처리. 실제 서비스에서는 Storage URL 써야 함
|
||||
createdAt: Timestamp.now()
|
||||
});
|
||||
|
||||
reset();
|
||||
goto(`/viewimage?id=${docRef.id}`);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
@ -116,45 +129,10 @@
|
|||
showImageError = false;
|
||||
}
|
||||
|
||||
function isCustomLocation() {
|
||||
return selectedLocation === 'custom';
|
||||
}
|
||||
|
||||
function removeImage(imageToRemove: File) {
|
||||
images = images.filter(img => img !== imageToRemove);
|
||||
}
|
||||
|
||||
function handleAddMemory() {
|
||||
showLocationError = selectedLocation === '' || (selectedLocation === 'custom' && customLocation.trim() === '');
|
||||
showImageError = images.length === 0;
|
||||
|
||||
if (showLocationError || showImageError) return;
|
||||
|
||||
const finalLocation = selectedLocation === 'custom' ? customLocation : selectedLocation;
|
||||
|
||||
const memory = {
|
||||
location: finalLocation,
|
||||
images,
|
||||
startDate,
|
||||
endDate
|
||||
};
|
||||
|
||||
// link data later...
|
||||
const params = new URLSearchParams({
|
||||
location: finalLocation,
|
||||
startDate,
|
||||
endDate
|
||||
});
|
||||
|
||||
goto(`/viewimage?${params.toString()}`);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
// needs to link with plan data set
|
||||
const locations = ['Paris', 'Tokyo', 'New York'];
|
||||
</script>
|
||||
|
||||
|
||||
{#if showPopup}
|
||||
<div class="overlay">
|
||||
<div class="popup {showLocationError || showImageError ? 'error' : ''}">
|
||||
|
|
|
@ -1,43 +1,89 @@
|
|||
<script>
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import '../../app.css';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Nav from '$lib/components/Nav.svelte';
|
||||
import { currentMemory } from '$lib/stores/memory';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
let location = '';
|
||||
let startDate = '';
|
||||
let endDate = '';
|
||||
let memory = get(currentMemory);
|
||||
|
||||
$: {
|
||||
const q = $page.url.searchParams;
|
||||
location = q.get('location') ?? '';
|
||||
startDate = q.get('startDate') ?? '';
|
||||
endDate = q.get('endDate') ?? '';
|
||||
}
|
||||
// 메인 이미지
|
||||
let mainImageUrl = memory?.images?.[0]
|
||||
? typeof memory.images[0] === 'string'
|
||||
? memory.images[0]
|
||||
: URL.createObjectURL(memory.images[0])
|
||||
: '';
|
||||
|
||||
// 컬럼별 대표 색 (예시용)
|
||||
let gradientColors = ['#e74c3c', '#f1c40f', '#2ecc71', '#3498db', '#9b59b6'];
|
||||
|
||||
$: gradientStyle = `conic-gradient(${[...gradientColors, gradientColors[0]].join(', ')})`;
|
||||
</script>
|
||||
|
||||
<div class="memory-view">
|
||||
<h2>{location}</h2>
|
||||
<p>{startDate} - {endDate}</p>
|
||||
<main>
|
||||
<Nav activeTab="Memory" />
|
||||
|
||||
<div class="gradient-wheel" style="background-image: {gradientStyle};"></div>
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
<h1>Memory View</h1>
|
||||
</div>
|
||||
|
||||
{#if memory}
|
||||
<div class="memory-container">
|
||||
<h2>{memory.location}</h2>
|
||||
<p>{memory.startDate} - {memory.endDate}</p>
|
||||
|
||||
<div class="visual-section">
|
||||
<!-- 🎨 gradient wheel -->
|
||||
<div
|
||||
class="gradient-wheel"
|
||||
style="background-image: {gradientStyle}; width: 300px; height: 300px"
|
||||
></div>
|
||||
|
||||
<!-- 📸 main image -->
|
||||
<img
|
||||
class="main-image"
|
||||
src={mainImageUrl}
|
||||
alt="Main Memory Image"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<p>Memory not loaded.</p>
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.memory-view {
|
||||
.content {
|
||||
padding: 2rem;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.memory-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.visual-section {
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.gradient-wheel {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin: 2rem auto;
|
||||
border-radius: 50%;
|
||||
background: var(--gradient);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.main-image {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
border-radius: 12px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user