Skip to content

Commit

Permalink
Add session information to votes
Browse files Browse the repository at this point in the history
  • Loading branch information
jevakallio committed Oct 24, 2023
1 parent ca83d8c commit 4ba7ac8
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 8 deletions.
16 changes: 11 additions & 5 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { Session, SessionProvider } from "@/components/Session";

const inter = Inter({ subsets: ["latin"] });

Expand All @@ -17,11 +18,16 @@ export default function RootLayout({
return (
<html lang="en">
<body className={inter.className}>
<div className="flex w-screen h-screen p-8">
<main className="relative m-auto h-full w-screen md:w-2/3 xl:w-1/2 md:h-auto p-8 md:rounded-xl md:shadow-xl bg-white">
{children}
</main>
</div>
<SessionProvider>
<div className="flex w-screen h-screen p-8">
<main className="relative m-auto h-full w-screen md:w-2/3 xl:w-1/2 md:h-auto p-8 md:rounded-xl md:shadow-xl bg-white">
{children}
</main>
</div>
<div className="absolute w-full bottom-10 flex justify-center">
<Session />
</div>
</SessionProvider>
</body>
</html>
);
Expand Down
1 change: 1 addition & 0 deletions app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export type Poll = {
title: string;
options: string[];
votes?: number[];
ownVote?: number;
};
40 changes: 37 additions & 3 deletions components/PollUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,33 @@
import { PARTYKIT_HOST } from "@/app/env";
import { Poll } from "@/app/types";
import usePartySocket from "partysocket/react";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import PollOptions from "./PollOptions";

const useSessionId = () => {
const nextAuthSession = useSession();
const [sessionId, setSessionId] = useState<string | null>(null);

useEffect(() => {
if (nextAuthSession.status === "authenticated") {
fetch("/session", { method: "POST" })
.then((res) => res.json())
.then((session) => setSessionId(session.id));
}
if (nextAuthSession.status === "unauthenticated") {
let localSessionId = localStorage?.getItem("sessionId");
if (!localSessionId) {
localSessionId = Math.random().toString(36).substring(2, 10);
localStorage?.setItem("sessionId", localSessionId);
}
setSessionId(localSessionId);
}
}, [nextAuthSession.status]);

return sessionId;
};

export default function PollUI({
id,
options,
Expand All @@ -15,6 +39,7 @@ export default function PollUI({
options: string[];
initialVotes?: number[];
}) {
const sessionId = useSessionId();
const [votes, setVotes] = useState<number[]>(initialVotes ?? []);
const [vote, setVote] = useState<number | null>(null);

Expand All @@ -26,16 +51,25 @@ export default function PollUI({
if (message.votes) {
setVotes(message.votes);
}
if (message.ownVote) {
setVote(message.ownVote);
}
},
});

const sendVote = (option: number) => {
const sendVote = async (option: number) => {
if (vote === null) {
socket.send(JSON.stringify({ type: "vote", option }));
socket.send(JSON.stringify({ type: "vote", option, sessionId }));
setVote(option);
}
};

useEffect(() => {
if (socket && sessionId) {
socket.send(JSON.stringify({ type: "identify", sessionId }));
}
}, [socket, sessionId]);

return (
<PollOptions
options={options}
Expand Down
34 changes: 34 additions & 0 deletions components/Session.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { signOut, signIn, useSession } from "next-auth/react";

export { SessionProvider } from "next-auth/react";

export function Session() {
const session = useSession();

switch (session.status) {
case "authenticated":
return (
<button
onClick={() => signOut({ callbackUrl: `${window.location.href}` })}
className="underline text-white text-sm"
>
Sign out
</button>
);
case "unauthenticated":
return (
<button
className="underline text-white text-sm"
onClick={() =>
signIn("github", { callbackUrl: `${window.location.href}` })
}
>
Sign in with GitHub
</button>
);
default:
return null;
}
}
15 changes: 15 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
const PARTYKIT_HOST = process.env.NEXT_PUBLIC_PARTYKIT_HOST || "127.0.0.1:1999";
const PARTYKIT_PROTOCOL =
PARTYKIT_HOST?.startsWith("localhost") ||
PARTYKIT_HOST?.startsWith("127.0.0.1")
? "http"
: "https";
const PARTYKIT_URL = `${PARTYKIT_PROTOCOL}://${PARTYKIT_HOST}`;

/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
serverActions: true,
},
rewrites: async () => [
{
// forward room authentication request to partykit
source: "/session",
destination: PARTYKIT_URL + "/session",
},
],
};

module.exports = nextConfig;

0 comments on commit 4ba7ac8

Please sign in to comment.