Skip to content

Commit

Permalink
Recent session (#63)
Browse files Browse the repository at this point in the history
* Recent host session

* Recent participant sessions

* fix lint

What
  • Loading branch information
180079995 authored Dec 24, 2024
1 parent 1728808 commit 9fbb9f5
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 22 deletions.
36 changes: 20 additions & 16 deletions src/lib/components/session/HostView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
import { Alert } from 'flowbite-svelte';
import type { Group } from '$lib/schema/group';
import { onMount } from 'svelte';
import { collection, getDocs, onSnapshot, getDoc, doc, Timestamp } from 'firebase/firestore';
import {
collection,
getDocs,
onSnapshot,
Timestamp,
query,
where,
limit
} from 'firebase/firestore';
import { db } from '$lib/firebase';
import { writable } from 'svelte/store';
import { getUser } from '$lib/utils/getUser';
Expand Down Expand Up @@ -122,37 +130,33 @@
};
});
// 生成代碼
async function genCode() {
const response = await fetch(`/api/session/${$page.params.id}/action/generate-code`, {
method: 'POST'
});
if (!response.ok) {
const data = await response.json();
notifications.error(data.error || '無法生成代碼');
return '';
}
const data = await response.json();
return data.code.toString();
}
async function getCode() {
const codeCollection = doc(db, 'temp_codes', $page.params.id);
const codeDoc = await getDoc(codeCollection);
if (
!codeDoc.exists() ||
Timestamp.now().toMillis() - codeDoc.data()?.createTime.toMillis() > 3600000
) {
const codeQuery = query(
collection(db, 'temp_codes'),
where('sessionId', '==', $page.params.id),
limit(1)
);
const codeDoc = (await getDocs(codeQuery)).docs[0];
console.log(codeDoc.data());
if (!codeDoc || Timestamp.now().toMillis() - codeDoc.data()?.createTime.toMillis() > 3600000) {
code = await genCode();
} else {
const checkValid = doc(db, 'temp_codes', codeDoc.data()?.code.toString());
const checkDoc = await getDoc(checkValid);
if (!checkDoc.exists() || checkDoc.data()?.sessionId !== $page.params.id) {
code = await genCode();
} else {
code = codeDoc.data()?.code;
}
code = codeDoc.id;
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/routes/api/session/[id]/action/[action]/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ export const POST: RequestHandler = async ({ params, locals }) => {
sessionId: sessionRef.id,
createTime: now
});
Codes = adminDb.collection('temp_codes').doc(sessionRef.id);
await Codes.set({
code: code,
createTime: now
});
}
return json({ code: code?.toString() });
} else {
Expand Down
120 changes: 119 additions & 1 deletion src/routes/dashboard/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
<script lang="ts">
import { onDestroy } from 'svelte';
import { writable } from 'svelte/store';
import { Card, Button } from 'flowbite-svelte';
import { MessageSquarePlus, UserPlus, UserCog, GitFork } from 'lucide-svelte';
import { collection, orderBy, limit, query, where } from 'firebase/firestore';
import {
collection,
orderBy,
limit,
query,
where,
Timestamp,
collectionGroup,
doc,
getDoc,
getDocs
} from 'firebase/firestore';
import { user } from '$lib/stores/auth';
import { profile } from '$lib/stores/profile';
import { db } from '$lib/firebase';
import { subscribeAll } from '$lib/firebase/store';
import type { Template } from '$lib/schema/template';
import type { Session } from '$lib/schema/session';
import { goto } from '$app/navigation';
import { createTemplate } from './createTemplate';
import { notifications } from '$lib/stores/notifications';
Expand All @@ -34,6 +47,37 @@
)
);
let [hostSessions, { unsubscribe: unsubscribe3 }] = subscribeAll<Session>(
query(
collection(db, 'sessions'),
where('host', '==', data.user.uid),
orderBy('createdAt', 'desc'),
limit(6)
)
);
// list of Sessions
let sessions = writable<[string, string, Session][]>([]);
async function getSessions() {
const sessionQuery = query(
collectionGroup(db, 'groups'),
where('participants', 'array-contains', data.user.uid),
limit(6)
);
const sessionSnapshot = await getDocs(sessionQuery);
sessionSnapshot.forEach(async (docu) => {
const session = await getDoc(docu.ref.parent.parent!);
const host = await getDoc(doc(db, 'profiles', session.data()?.host));
sessions.update((value) => [
...value,
[host.data()?.displayName, session.id, session.data() as Session]
]);
});
}
getSessions();
async function handleCreateTemplate() {
try {
const id = await createTemplate();
Expand Down Expand Up @@ -67,6 +111,7 @@
onDestroy(() => {
unsubscribe1();
unsubscribe2();
unsubscribe3();
});
</script>

Expand Down Expand Up @@ -214,4 +259,77 @@
{/if}
</div>
</div>

<!-- Recent Session -->
<div class="mt-16">
<div class="mb-6 flex items-center justify-between">
<h2 class="text-2xl font-semibold text-gray-900">Recent Host Sessions</h2>
</div>
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{#if $hostSessions?.length}
{#each $hostSessions as [doc, session]}
<Card padding="lg" class="transition-all hover:border-primary-500">
<div>
<h3 class="mb-2 text-xl font-bold">{session.title}</h3>
<p class="mb-4 line-clamp-2 text-gray-600">{session.task}</p>
<p class="mb-4 line-clamp-2 text-blue-600">Now is in {session.status} stage.</p>
<div class="mb-4 flex items-center gap-4">
<span class="text-sm text-gray-500">
{(session.createdAt as Timestamp).toDate().toLocaleString()}
</span>
</div>
<Button href="/session/{doc.id}" class="w-full">View Session</Button>
</div>
</Card>
{/each}
{:else}
<Card class="md:col-span-2 lg:col-span-3">
<div class="p-8 text-center">
<div class="mb-4 inline-flex rounded-full bg-primary-100 p-4">
<MessageSquarePlus size={32} class="text-primary-600" />
</div>
<p class="mb-2 text-lg font-medium text-gray-900">No sessions created yet</p>
<p class="mb-4 text-gray-600">Create a new session with template</p>
</div>
</Card>
{/if}
</div>
</div>

<!-- Recent participant Session-->
<div class="mt-16">
<div class="mb-6 flex items-center justify-between">
<h2 class="text-2xl font-semibold text-gray-900">Recent Participant Sessions</h2>
</div>
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{#if $sessions.length}
{#each $sessions as [hoster, docid, session]}
<Card padding="lg" class="transition-all hover:border-primary-500">
<div>
<h3 class="mb-2 text-xl font-bold">{session.title}</h3>
<p class="mb-4 line-clamp-2 text-gray-600">{session.task}</p>
<p class="mb-4 line-clamp-2 text-blue-600">Now is in {session.status} stage.</p>
<p class="line-clamp-2 text-gray-500">Host by: {hoster}</p>
<div class="mb-4 flex items-center gap-4">
<span class="text-sm text-gray-500">
{(session.createdAt as Timestamp).toDate().toLocaleString()}
</span>
</div>
<Button href="/session/{docid}" class="w-full">View Session</Button>
</div>
</Card>
{/each}
{:else}
<Card class="md:col-span-2 lg:col-span-3">
<div class="p-8 text-center">
<div class="mb-4 inline-flex rounded-full bg-primary-100 p-4">
<MessageSquarePlus size={32} class="text-primary-600" />
</div>
<p class="mb-2 text-lg font-medium text-gray-900">No sessions joined yet</p>
<Button href="/join" color="primary" class="w-full">Join a session</Button>
</div>
</Card>
{/if}
</div>
</div>
</main>

0 comments on commit 9fbb9f5

Please sign in to comment.