Implementation, thanks amp

This commit is contained in:
2026-03-16 23:03:27 +13:00
parent b7539ac86e
commit ab508d827d
45 changed files with 2705 additions and 26 deletions

View File

@@ -0,0 +1,157 @@
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<Poll[]>([]);
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<void> {
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<Poll> {
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<void> {
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<Poll | undefined> {
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<void> {
await dbDeletePoll(id);
polls = polls.filter((p) => p.id !== id);
}
export async function addOptionToPoll(pollId: string, text: string): Promise<PollOption | null> {
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<Vote | null> {
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<void> {
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<void> {
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<void> {
const poll = getPollById(pollId);
if (!poll) return;
const updated = { ...poll, roles: poll.roles.filter((r) => r.userId !== userId) };
await updatePollInStore(updated);
}