import { loadAllPolls, savePoll, deletePoll as dbDeletePoll, loadPoll } from '$lib/db.js'; import type { Poll, PollOption, Vote, RoleAssignment } from '$lib/types.js'; import { getUserId } from '$lib/crypto.js'; let polls = $state([]); let loading = $state(true); export function getPolls() { return { get all() { return polls; }, get loading() { return loading; }, get owned() { const id = currentUserId; return id ? polls.filter((p) => p.ownerId === id) : []; }, get participating() { const id = currentUserId; return id ? polls.filter((p) => p.ownerId !== id) : []; } }; } let currentUserId: string | null = null; export async function initPolls(): Promise { loading = true; currentUserId = await getUserId(); polls = await loadAllPolls(); loading = false; } export async function createPoll(data: { title: string; description: string; anonymous: boolean; visibility: Poll['visibility']; options?: string[]; }): Promise { const userId = await getUserId(); const now = Date.now(); const poll: Poll = { id: crypto.randomUUID(), ownerId: userId, title: data.title, description: data.description, anonymous: data.anonymous, status: 'draft', visibility: data.visibility, createdAt: now, options: (data.options ?? []).map((text) => ({ id: crypto.randomUUID(), text, addedBy: userId, addedAt: now })), votes: [], roles: [] }; await savePoll(poll); polls = [...polls, poll]; return poll; } export async function updatePollInStore(poll: Poll): Promise { await savePoll(poll); polls = polls.map((p) => (p.id === poll.id ? poll : p)); } export function getPollById(id: string): Poll | undefined { return polls.find((p) => p.id === id); } export async function refreshPoll(id: string): Promise { const poll = await loadPoll(id); if (poll) { polls = polls.map((p) => (p.id === id ? poll : p)); if (!polls.find((p) => p.id === id)) { polls = [...polls, poll]; } } return poll; } export async function deletePollFromStore(id: string): Promise { await dbDeletePoll(id); polls = polls.filter((p) => p.id !== id); } export async function addOptionToPoll(pollId: string, text: string): Promise { const poll = getPollById(pollId); if (!poll || poll.status !== 'open') return null; const userId = await getUserId(); const option: PollOption = { id: crypto.randomUUID(), text, addedBy: userId, addedAt: Date.now() }; const updated = { ...poll, options: [...poll.options, option] }; await updatePollInStore(updated); return option; } export async function castVote(pollId: string, optionId: string): Promise { const poll = getPollById(pollId); if (!poll || poll.status !== 'open') return null; const userId = await getUserId(); const vote: Vote = { optionId, voterId: poll.anonymous ? null : userId, timestamp: Date.now() }; // Remove previous vote by this user (for vote changes) const filteredVotes = poll.anonymous ? poll.votes // Can't deduplicate anonymous votes by voterId : poll.votes.filter((v) => v.voterId !== userId); const updated = { ...poll, votes: [...filteredVotes, vote] }; await updatePollInStore(updated); return vote; } export async function setPollStatus(pollId: string, status: Poll['status']): Promise { const poll = getPollById(pollId); if (!poll) return; const updated = { ...poll, status, ...(status === 'closed' ? { closedAt: Date.now() } : {}) }; await updatePollInStore(updated); } export async function setRole(pollId: string, userId: string, role: RoleAssignment['role']): Promise { const poll = getPollById(pollId); if (!poll) return; const roles = poll.roles.filter((r) => r.userId !== userId); roles.push({ userId, role }); const updated = { ...poll, roles }; await updatePollInStore(updated); } export async function removeRole(pollId: string, userId: string): Promise { const poll = getPollById(pollId); if (!poll) return; const updated = { ...poll, roles: poll.roles.filter((r) => r.userId !== userId) }; await updatePollInStore(updated); }