Movie List에서 나로 할당된 작업목록만 보이도록 추가

This commit is contained in:
birdhead 2025-10-22 01:09:31 +00:00
parent 7227e70383
commit 328521ccd9
4 changed files with 95 additions and 25 deletions

View File

@ -1,9 +1,9 @@
// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';
import jwt from 'jsonwebtoken';
import { JWT_SECRET } from '$env/static/private';
const SECRET_KEY = 'my_secret_key'; // 실제 운영 시 .env 파일에 보관
const SECRET_KEY = JWT_SECRET;
export const handle: Handle = async ({ event, resolve }) => {
const token = event.cookies.get('session');
@ -26,4 +26,3 @@ export const handle: Handle = async ({ event, resolve }) => {
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
return response;
};

View File

@ -1,22 +1,52 @@
// =======================================================================
// src/routes/+page.server.ts (확장자 변경 및 타입 추가)
// =======================================================================
// src/routes/(protected)/bigdata-generate/+page.server.ts
import pool from '$lib/server/database';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async () => {
try {
const result = await pool.query<{ IndexMovie: number }>(
'SELECT DISTINCT "IndexMovie" FROM public."TumerDatasetRef" ORDER BY "IndexMovie" ASC'
);
return {
movies: result.rows.map(row => row.IndexMovie)
};
} catch (error) {
console.error("Failed to load initial movies", error);
return {
movies: [],
error: "데이터베이스에서 영화 목록을 가져오는 데 실패했습니다."
};
}
export const load: PageServerLoad = async (event) => {
const { user } = await event.parent();
// console.log('Parent로부터 받은 사용자 정보:', user); // 디버깅 완료 후 주석 처리
let myMovies: number[] = [];
let allMovies: number[] = [];
let error: string | null = null;
try {
// "전체" 목록 쿼리 (정상)
const allResult = await pool.query<{ IndexMovie: number }>(
'SELECT DISTINCT "IndexMovie" FROM public."TumerDatasetRef" ORDER BY "IndexMovie" ASC'
);
allMovies = allResult.rows.map((row) => row.IndexMovie);
if (user && user.workerId) {
// ▼▼▼ [ "내" 목록 쿼리 수정 ] ▼▼▼
// 2-1. 타입을 올바른 컬럼명 "Index"로 수정
const myResult = await pool.query<{ Index: number }>(
// 2-2. 쿼리는 "Index" 컬럼을 SELECT (정상)
'SELECT DISTINCT "Index" FROM public."TumerMovie" WHERE "WorkerID" = $1 ORDER BY "Index" ASC',
[user.workerId]
);
// 2-3. 매핑을 "row.IndexMovie"가 아닌 "row.Index"로 수정
myMovies = myResult.rows.map((row) => row.Index);
// ▲▲▲ [ 수정 완료 ] ▲▲▲
} else {
console.warn('user.workerId를 찾을 수 없거나 user가 null입니다.', user);
}
return {
allMovies,
myMovies
};
} catch (dbError: any) {
console.error('Failed to load movie lists', dbError);
return {
allMovies: [],
myMovies: [],
error: dbError.message || '데이터베이스에서 영화 목록을 가져오는 데 실패했습니다.'
};
}
};

View File

@ -1,3 +1,5 @@
<!-- src/routes/(protected)/bigdata-generate/+page.svelte -->
<script context="module" lang="ts">
// Declare global cv for TypeScript
declare let cv: any;
@ -49,6 +51,21 @@
let dataNumberPanel: HTMLDivElement;
let clipboard: Omit<Rectangle, 'id'>[] | null = null;
let movieFilter: 'my' | 'all' = 'my'; // 기본값 '나'
// 필터에 따라 보여줄 영화 목록을 동적으로 결정
$: displayedMovies = movieFilter === 'my' ? data.myMovies || [] : data.allMovies || [];
// 필터 변경 시, 현재 선택된 영화가 새 목록에 없으면 선택 해제
$: if (displayedMovies) {
if (selectedMovie && !displayedMovies.includes(selectedMovie)) {
selectedMovie = null;
selectedDataNumberInfo = null;
rectangles = [];
dataNumbers = [];
isLoadingDataNumbers = false;
}
}
// --- 반응형 로직 ---
let selectedRectangles: Rectangle[] = [];
$: selectedRectangles = rectangles.filter(r => selectedRectIds.includes(r.id));
@ -744,10 +761,31 @@
<div class="w-1/2 landscape:w-full lg:w-full h-full landscape:h-1/2 lg:h-1/2 flex flex-col gap-1">
<h2 class="flex-shrink-0 text-sm font-bold text-gray-600 uppercase tracking-wider px-1">Movie Index</h2>
<div class="flex-shrink-0 px-1 py-1 bg-gray-100 rounded-md flex justify-around gap-1">
<label class="flex-1 text-center text-sm px-2 py-1 rounded-md cursor-pointer transition-colors {movieFilter === 'my' ? 'bg-blue-600 text-white shadow' : 'text-gray-600 hover:bg-gray-200'}">
<input
type="radio"
bind:group={movieFilter}
value="my"
class="sr-only"
/>
나 (My)
</label>
<label class="flex-1 text-center text-sm px-2 py-1 rounded-md cursor-pointer transition-colors {movieFilter === 'all' ? 'bg-blue-600 text-white shadow' : 'text-gray-600 hover:bg-gray-200'}">
<input
type="radio"
bind:group={movieFilter}
value="all"
class="sr-only"
/>
전체 (All)
</label>
</div>
<div class="nav-section border bg-white border-gray-200 rounded-lg p-2 flex-grow overflow-y-auto min-h-0">
<ul class="space-y-1">
{#if data.movies && data.movies.length > 0}
{#each data.movies as movie}
{#if displayedMovies && displayedMovies.length > 0}
{#each displayedMovies as movie}
<li>
<button
on:click={() => selectMovie(movie)}
@ -762,8 +800,10 @@
{/each}
{:else if data.error}
<p class="text-sm text-red-500 px-3">{data.error}</p>
{:else if movieFilter === 'my'}
<p class="text-sm text-gray-500 px-3">내 작업 목록이 없습니다.</p>
{:else}
<p class="text-sm text-gray-500 px-3">No movies found.</p>
<p class="text-sm text-gray-500 px-3">전체 영화 목록이 없습니다.</p>
{/if}
</ul>
</div>

View File

@ -45,7 +45,8 @@ export const load: LayoutServerLoad = ({ cookies }) => {
id: decoded.id,
login_id: decoded.login_id,
name: decoded.name,
role: role //
role: role, // user role 추가
workerId: decoded.id // workerId 추가
};
// 6. 역할에 맞는 메뉴를 가져옵니다.