import { fail } from '@sveltejs/kit'; import { pb, generateShortCode, type Link, type Click, type User } from '$lib/pocketbase'; import { getCollection } from '$lib/content'; import type { BlogPostWithMeta } from '../content/config'; import type { Actions, PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ locals }) => { try { const filter = locals.user ? `user_id="${locals.user.id}"` : ''; const links = await locals.pb.collection('links').getList(1, locals.user ? 50 : 10, { filter, sort: '-created', expand: 'user', }); const linksWithClicks = await Promise.all( links.items.map(async (link) => { const clicks = await locals.pb.collection('clicks').getList(1, 1, { filter: `link_id="${link.id}"`, }); return { ...link, clicks: clicks.totalItems, }; }) ); // Fetch global statistics const [usersStats, linksStats, foldersStats, clicksStats] = await Promise.all([ locals.pb.collection('users').getList(1, 1), locals.pb.collection('links').getList(1, 1), locals.pb.collection('folders').getList(1, 1), locals.pb.collection('clicks').getList(1, 1), ]).catch(() => [{ totalItems: 0 }, { totalItems: 0 }, { totalItems: 0 }, { totalItems: 0 }]); // Fetch latest blog posts const blogPosts = await getCollection('blog').catch(() => []); return { links: linksWithClicks, globalStats: { totalUsers: usersStats.totalItems || 0, totalLinks: linksStats.totalItems || 0, totalFolders: foldersStats.totalItems || 0, totalClicks: clicksStats.totalItems || 0, }, blogPosts: blogPosts.slice(0, 3), }; } catch (err) { return { links: [], globalStats: { totalUsers: 0, totalLinks: 0, totalFolders: 0, totalClicks: 0, }, }; } }; export const actions = { create: async ({ request, url, locals }) => { console.log('🎯 Home page: Create action called'); console.log('User:', locals.user?.id || 'Anonymous'); const data = await request.formData(); const urlToShorten = data.get('url') as string; const title = data.get('title') as string; const description = data.get('description') as string; const expiresIn = data.get('expires_in') as string; const maxClicks = data.get('max_clicks') as string; const password = data.get('password') as string; console.log('📦 Form data:', { url: urlToShorten, title, expiresIn, maxClicks, hasPassword: !!password, }); if (!urlToShorten) { console.error('❌ No URL provided'); return fail(400, { error: 'URL is required' }); } // Get user's personal workspace if logged in let workspaceId = null; if (locals.user?.id) { try { const workspaces = await locals.pb.collection('workspaces').getList(1, 1, { filter: `owner="${locals.user.id}" && type="personal"`, }); if (workspaces.items.length > 0) { workspaceId = workspaces.items[0].id; } } catch (err) { console.error('Error fetching workspace:', err); } } let shortCode = generateShortCode(); let attempts = 0; const maxAttempts = 10; while (attempts < maxAttempts) { try { let expiresAt = null; if (expiresIn) { const days = parseInt(expiresIn); if (!isNaN(days) && days > 0) { const date = new Date(); date.setDate(date.getDate() + days); expiresAt = date.toISOString(); } } console.log('🔄 Attempting to create link with code:', shortCode); const link = await locals.pb.collection('links').create({ workspace_id: workspaceId, user_id: locals.user?.id || null, original_url: urlToShorten, short_code: shortCode, title: title || '', description: description || '', is_active: true, expires_at: expiresAt, max_clicks: maxClicks ? parseInt(maxClicks) : null, password: password || null, }); console.log('✅ Link created successfully:', link); return { success: true, shortUrl: `${url.origin}/${link.short_code}`, link, }; } catch (err: any) { console.error('❌ Error creating link:', err); console.error('Error details:', { message: err?.message, data: err?.data, response: err?.response, }); if (err?.data?.data?.short_code?.code === 'validation_not_unique') { shortCode = generateShortCode(); attempts++; console.log('🔄 Code collision, retrying with:', shortCode); } else { console.error('🔥 Fatal error, returning failure'); return fail(400, { error: err?.message || 'Failed to create short link' }); } } } return fail(400, { error: 'Could not generate unique short code' }); }, delete: async ({ request, locals }) => { const data = await request.formData(); const id = data.get('id') as string; try { await locals.pb.collection('links').delete(id); return { deleted: true }; } catch (err) { return fail(400, { error: 'Failed to delete link' }); } }, } satisfies Actions;