link mwmory part to firebase

This commit is contained in:
Chaebean Yang 2025-06-06 19:19:28 +09:00
parent bd6b405478
commit 8ef8712a76
3 changed files with 120 additions and 82 deletions

View File

@ -5,11 +5,18 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { Loader } from '@googlemaps/js-api-loader'; import { Loader } from '@googlemaps/js-api-loader';
import { collection, addDoc, getFirestore, Timestamp } from 'firebase/firestore'; import { collection, addDoc, getFirestore, Timestamp } from 'firebase/firestore';
import { app } from '$lib/firebase'; import { ref, push } from 'firebase/database';
import { db } from '../../firebase';
export let showPopup = false; export let showPopup = false;
$: console.log('Popup received prop:', showPopup);
export let onAddMemory = () => {}; export let onAddMemory = () => {};
export let onCancel = () => {}; export let onCancel = () => {};
function handleCancelClick() {
onCancel();
reset();
}
let startDate = ''; let startDate = '';
let endDate = ''; let endDate = '';
@ -98,25 +105,30 @@
} }
async function handleAddMemory() { async function handleAddMemory() {
showLocationError = selectedLocation === '' || (isCustomLocation() && customLocation.trim() === ''); showLocationError = selectedLocation === '' || (isCustomLocation() && customLocation.trim() === '');
showImageError = images.length === 0; showImageError = images.length === 0;
if (showLocationError || showImageError) return; if (showLocationError || showImageError) return;
const finalLocation = isCustomLocation() ? customLocation : selectedLocation; const finalLocation = isCustomLocation() ? customLocation : selectedLocation;
const db = getFirestore(app); const newMemory = {
const docRef = await addDoc(collection(db, 'memories'), { location: finalLocation,
location: finalLocation, startDate,
startDate, endDate,
endDate, images: images.map(file => URL.createObjectURL(file)),
images: images.map(file => URL.createObjectURL(file)), // 임시 처리. 실제 서비스에서는 Storage URL 써야 함 createdAt: new Date().toISOString()
createdAt: Timestamp.now() };
});
try {
reset(); const newMemoryRef = ref(db, 'memories');
goto(`/viewimage?id=${docRef.id}`); const addedRef = await push(newMemoryRef, newMemory);
} reset();
goto(`/viewimage?id=${addedRef.key}`);
} catch (error) {
console.error('Error saving memory:', error);
}
}
function reset() { function reset() {
showPopup = false; showPopup = false;

View File

@ -1,5 +1,5 @@
<script> <script>
import '/src/app.css'; import '../../app.css'
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import WorldMap from '$lib/components/WorldMap.svelte'; import WorldMap from '$lib/components/WorldMap.svelte';
import Button from '$lib/components/Button.svelte'; import Button from '$lib/components/Button.svelte';

View File

@ -1,89 +1,115 @@
<script> <script>
import '../../app.css'; import '../../app.css';
import Button from '$lib/components/Button.svelte';
import Nav from '$lib/components/Nav.svelte'; import Nav from '$lib/components/Nav.svelte';
import { currentMemory } from '$lib/stores/memory'; import Button from '$lib/components/Button.svelte';
import { get } from 'svelte/store'; import { page } from '$app/stores';
import { onMount } from 'svelte';
import { getDatabase, ref, get } from 'firebase/database';
import { db } from '../../firebase';
let memory = get(currentMemory); let memoryId = '';
let memory = null;
// 메인 이미지 $: {
let mainImageUrl = memory?.images?.[0] const q = $page.url.searchParams;
? typeof memory.images[0] === 'string' memoryId = q.get('id') ?? '';
? memory.images[0] }
: URL.createObjectURL(memory.images[0])
: ''; onMount(async () => {
if (memoryId) {
const snapshot = await get(ref(db, `memories/${memoryId}`));
if (snapshot.exists()) {
memory = snapshot.val();
} else {
console.error('No memory found');
}
}
});
// 컬럼별 대표 색 (예시용)
let gradientColors = ['#e74c3c', '#f1c40f', '#2ecc71', '#3498db', '#9b59b6']; let gradientColors = ['#e74c3c', '#f1c40f', '#2ecc71', '#3498db', '#9b59b6'];
$: gradientStyle = `conic-gradient(${[...gradientColors, gradientColors[0]].join(', ')})`; $: gradientStyle = `
conic-gradient(
${gradientColors.map((c, i) => `${c} ${i * 72}deg ${(i + 1) * 72}deg`).join(',')}
)
`;
</script> </script>
<main> <main>
<Nav activeTab="Memory" /> <Nav activeTab="MyMemory" darkMode={true}/>
<div class="content"> <div class="content">
<div class="header">
<h1>Memory View</h1>
</div>
{#if memory} {#if memory}
<div class="memory-container"> <div class="header">
<h2>{memory.location}</h2> <h1>{memory.location}</h1>
<p>{memory.startDate} - {memory.endDate}</p> <p>{memory.startDate} - {memory.endDate}</p>
</div>
<div class="visual-section"> <div class="wheel-container">
<!-- 🎨 gradient wheel --> <div class="gradient-wheel" style="background-image: {gradientStyle};"></div>
<div </div>
class="gradient-wheel"
style="background-image: {gradientStyle}; width: 300px; height: 300px"
></div>
<!-- 📸 main image --> <div class="image-list">
<img {#each memory.images as img}
class="main-image" <img src={typeof img === 'string' ? img : URL.createObjectURL(img)} alt="Memory image" />
src={mainImageUrl} {/each}
alt="Main Memory Image"
/>
</div>
</div> </div>
{:else} {:else}
<p>Memory not loaded.</p> <p class="empty">Loading memory...</p>
{/if} {/if}
</div> </div>
</main> </main>
<style> <style>
.content { main {
padding: 2rem; height: 100vh;
} background-color: var(--black);
font-family: 'Inter', sans-serif;
display: flex;
flex-direction: column;
}
.header { .content {
margin-bottom: 2rem; flex: 1;
} padding: 2rem 1rem;
overflow-y: auto;
}
.memory-container { .header {
text-align: center; text-align: center;
} color: var(--white);
margin-bottom: 2rem;
}
.visual-section { .gradient-wheel {
margin-top: 2rem; width: 300px;
display: flex; height: 300px;
flex-direction: column; margin: 2rem auto;
align-items: center; border-radius: 50%;
gap: 2rem; box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
} }
.gradient-wheel { .wheel-container {
border-radius: 50%; display: flex;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); justify-content: center;
} }
.main-image { .image-list {
width: 300px; display: flex;
height: auto; flex-direction: column;
border-radius: 12px; align-items: center;
object-fit: cover; gap: 1rem;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.2); margin-top: 2rem;
} }
</style>
.image-list img {
width: 80%;
max-width: 500px;
border-radius: 12px;
}
.empty {
color: var(--gray-400);
text-align: center;
margin-top: 4rem;
}
</style>