From 2284f94ee33ca8e5bdd31c710f5c6bc5e827b3f4 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Mon, 29 Dec 2025 21:19:03 +0100 Subject: [PATCH] feat: Auto-load saved user and remember last visited room MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JoinForm now pre-populates name/emoji from localStorage and shows a "Quick Join as [name]" button for returning users - Home page shows "Rejoin /[room]" button when user has visited before - Room slug saved to localStorage on every visit for quick rejoin 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/app/[slug]/page.tsx | 3 +++ src/app/page.tsx | 31 +++++++++++++++++++++ src/components/room/JoinForm.tsx | 46 ++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/app/[slug]/page.tsx b/src/app/[slug]/page.tsx index 765d6e7..a99c801 100644 --- a/src/app/[slug]/page.tsx +++ b/src/app/[slug]/page.tsx @@ -46,6 +46,8 @@ export default function RoomPage() { const stored = localStorage.getItem('rmaps_user'); if (stored) { setCurrentUser(JSON.parse(stored)); + // Save this as the last visited room + localStorage.setItem('rmaps_last_room', slug); // Check if user had location sharing enabled for this room const sharingPref = localStorage.getItem(`rmaps_sharing_${slug}`); if (sharingPref === 'true') { @@ -61,6 +63,7 @@ export default function RoomPage() { const handleJoin = (name: string, emoji: string) => { const user = { name, emoji }; localStorage.setItem('rmaps_user', JSON.stringify(user)); + localStorage.setItem('rmaps_last_room', slug); setCurrentUser(user); setNeedsJoin(false); }; diff --git a/src/app/page.tsx b/src/app/page.tsx index 6027200..37ddc3a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -20,6 +20,7 @@ export default function HomePage() { const [emoji, setEmoji] = useState(''); const [roomName, setRoomName] = useState(''); const [isLoaded, setIsLoaded] = useState(false); + const [lastRoom, setLastRoom] = useState(null); // Load saved user info from localStorage on mount useEffect(() => { @@ -34,6 +35,11 @@ export default function HomePage() { loadedEmoji = user.emoji; } } + // Load last visited room + const lastVisited = localStorage.getItem('rmaps_last_room'); + if (lastVisited) { + setLastRoom(lastVisited); + } } catch { // Ignore parse errors } @@ -53,6 +59,7 @@ export default function HomePage() { // Store user info in localStorage for the session localStorage.setItem('rmaps_user', JSON.stringify({ name, emoji })); + localStorage.setItem('rmaps_last_room', slug); // Navigate to the room (will create it if it doesn't exist) router.push(`/${slug}`); @@ -65,9 +72,16 @@ export default function HomePage() { // Clean the slug const cleanSlug = joinSlug.toLowerCase().replace(/[^a-z0-9-]/g, ''); + localStorage.setItem('rmaps_last_room', cleanSlug); router.push(`/${cleanSlug}`); }; + const handleRejoinLastRoom = () => { + if (!name.trim() || !lastRoom) return; + localStorage.setItem('rmaps_user', JSON.stringify({ name, emoji })); + router.push(`/${lastRoom}`); + }; + return (
@@ -79,6 +93,23 @@ export default function HomePage() {

Find your friends at events

+ {/* Quick Rejoin Card - show when user has saved info and last room */} + {isLoaded && name && lastRoom && ( +
+

Welcome back, {name}!

+ +

+ Or create/join a different room below +

+
+ )} + {/* Main Card */}
{/* User Setup */} diff --git a/src/components/room/JoinForm.tsx b/src/components/room/JoinForm.tsx index 59cf0c0..61ef16f 100644 --- a/src/components/room/JoinForm.tsx +++ b/src/components/room/JoinForm.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; const EMOJIS = ['😀', '😎', '🤓', '🥳', '🦊', '🐱', '🐶', '🦄', '🌟', '🔥', '💜', '🎮']; @@ -11,7 +11,31 @@ interface JoinFormProps { export default function JoinForm({ roomSlug, onJoin }: JoinFormProps) { const [name, setName] = useState(''); - const [emoji, setEmoji] = useState(EMOJIS[Math.floor(Math.random() * EMOJIS.length)]); + const [emoji, setEmoji] = useState(''); + const [isLoaded, setIsLoaded] = useState(false); + + // Load saved user info from localStorage + useEffect(() => { + let loadedEmoji = ''; + try { + const stored = localStorage.getItem('rmaps_user'); + if (stored) { + const user = JSON.parse(stored); + if (user.name) setName(user.name); + if (user.emoji) { + setEmoji(user.emoji); + loadedEmoji = user.emoji; + } + } + } catch { + // Ignore parse errors + } + // Set random emoji if none loaded + if (!loadedEmoji) { + setEmoji(EMOJIS[Math.floor(Math.random() * EMOJIS.length)]); + } + setIsLoaded(true); + }, []); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -30,6 +54,24 @@ export default function JoinForm({ roomSlug, onJoin }: JoinFormProps) {

+ {/* Quick join option if user already has saved info */} + {isLoaded && name && ( +
+

Welcome back!

+ +

+ Or customize below +

+
+ )} +
{/* Emoji picker */}