feat: Auto-load saved user and remember last visited room
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
47dea7c9c3
commit
2284f94ee3
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<string | null>(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 (
|
||||
<main className="min-h-screen flex flex-col items-center justify-center p-4">
|
||||
<div className="max-w-md w-full space-y-8">
|
||||
|
|
@ -79,6 +93,23 @@ export default function HomePage() {
|
|||
<p className="text-white/60">Find your friends at events</p>
|
||||
</div>
|
||||
|
||||
{/* Quick Rejoin Card - show when user has saved info and last room */}
|
||||
{isLoaded && name && lastRoom && (
|
||||
<div className="room-panel rounded-2xl p-6">
|
||||
<p className="text-white/60 text-sm text-center mb-4">Welcome back, {name}!</p>
|
||||
<button
|
||||
onClick={handleRejoinLastRoom}
|
||||
className="btn-primary w-full text-lg py-3 flex items-center justify-center gap-2"
|
||||
>
|
||||
<span className="text-xl">{emoji}</span>
|
||||
<span>Rejoin /{lastRoom}</span>
|
||||
</button>
|
||||
<p className="text-white/40 text-xs text-center mt-3">
|
||||
Or create/join a different room below
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Main Card */}
|
||||
<div className="room-panel rounded-2xl p-6 space-y-6">
|
||||
{/* User Setup */}
|
||||
|
|
|
|||
|
|
@ -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) {
|
|||
</p>
|
||||
</div>
|
||||
|
||||
{/* Quick join option if user already has saved info */}
|
||||
{isLoaded && name && (
|
||||
<div className="mb-6 p-4 bg-rmaps-primary/10 border border-rmaps-primary/30 rounded-lg">
|
||||
<p className="text-white/60 text-sm mb-3 text-center">Welcome back!</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onJoin(name.trim(), emoji)}
|
||||
className="w-full btn-primary py-3 flex items-center justify-center gap-2"
|
||||
>
|
||||
<span className="text-xl">{emoji}</span>
|
||||
<span>Join as {name}</span>
|
||||
</button>
|
||||
<p className="text-white/40 text-xs text-center mt-2">
|
||||
Or customize below
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
{/* Emoji picker */}
|
||||
<div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue