Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
<!doctype html>
<html lang="en">
<html lang="en" suppressHydrationWarning>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PeerCall - Secure Privacy-Respecting Video Calls</title>
<script>
// Prevent flash of unstyled content - sync with next-themes
(function() {
try {
const theme = localStorage.getItem('peercall-theme');
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
} catch (e) {
// Ignore errors
}
})();
</script>
<meta name="description" content="Secure, privacy-respecting real-time video calls. PeerCall delivers peer-to-peer WebRTC video communication with strong authentication and session management." />
<meta name="author" content="PeerCall" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link href="./src/index.css" rel="stylesheet">
<!-- favicon (use the existing vite.svg as the icon) -->
<link rel="icon" type="image/svg+xml" href="/vite.svg">
<meta property="og:title" content="PeerCall - Secure Privacy-Respecting Video Calls" />
Expand All @@ -20,6 +34,5 @@
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script src="https://cdn.tailwindcss.com"></script>
</body>
</html>
2,594 changes: 1,479 additions & 1,115 deletions frontend/package-lock.json

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-toast": "^1.2.15",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.7",
"@tailwindcss/vite": "^4.1.14",
"@tanstack/react-query": "^5.90.3",
"axios": "^1.13.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand All @@ -29,20 +29,21 @@
"react-dom": "^19.2.0",
"react-hook-form": "^7.65.0",
"react-hotkeys": "^2.0.0",
"react-router-dom": "^7.9.4",
"react-router-dom": "^7.9.5",
"shadcn": "^3.4.1",
"socket.io-client": "^4.8.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.3.1"
"tailwind-merge": "^3.4.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.14",
"@tailwindcss/postcss": "^4.1.17",
"@tailwindcss/vite": "^4.1.17",
"@types/node": "^24.7.2",
"@vitejs/plugin-react-swc": "^4.1.0",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.6",
"rollup": "^4.52.5",
"tailwindcss": "^4.1.14",
"vite": "^7.1.11"
"tailwindcss": "^4.1.17",
"vite": "^7.2.2"
}
}
10 changes: 5 additions & 5 deletions frontend/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
plugins: [
require('@tailwindcss/postcss'),
require('autoprefixer')
]
import tailwindcss from "@tailwindcss/postcss";
import autoprefixer from "autoprefixer";

export default {
plugins: [tailwindcss(), autoprefixer()],
};
45 changes: 27 additions & 18 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,40 @@ import JoinRoom from "./pages/JoinRoom.js";
import InRoom from "./pages/InRoom.js";
import CreateRoomLobby from "./pages/CreateRoomLobby.js";
import CreateRoom from "./pages/CreateRoom.js";
import { ThemeProvider } from "next-themes";
import ActiveSessions from "./pages/ActiveSessions.js";
import InRoomWrapper from "./pages/InRoomWrapper.js";
const queryClient = new QueryClient();

const App = () => (
<ErrorBoundary>
<QueryClientProvider client={queryClient}>
<TooltipProvider>
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Index />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/room-actions" element={<RoomActions />} />
<Route path="/oauth-success" element={<OAuthSuccess />} />
<Route path="/create-room" element={<CreateRoom />} /> {/* ✅ */}
<Route path="/join-room" element={<JoinRoom />} /> {/* ✅ */}
<Route path="/room/:roomName" element={<InRoomWrapper />} />
<Route path="/lobby/:roomId" element={<CreateRoomLobby />} />
<Route path="/sessions" element={<ActiveSessions />} />
</Routes>
</BrowserRouter>
</TooltipProvider>
<ThemeProvider
attribute="class"
defaultTheme="light"
enableSystem={false}
storageKey="peercall-theme"
disableTransitionOnChange={false}
>
<TooltipProvider>
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Index />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/room-actions" element={<RoomActions />} />
<Route path="/oauth-success" element={<OAuthSuccess />} />
<Route path="/create-room" element={<CreateRoom />} /> {/* ✅ */}
<Route path="/join-room" element={<JoinRoom />} /> {/* ✅ */}
<Route path="/room/:roomName" element={<InRoomWrapper />} />
<Route path="/lobby/:roomId" element={<CreateRoomLobby />} />
<Route path="/sessions" element={<ActiveSessions />} />
</Routes>
</BrowserRouter>
</TooltipProvider>
</ThemeProvider>
</QueryClientProvider>
</ErrorBoundary>
);
Expand Down
26 changes: 13 additions & 13 deletions frontend/src/components/ChatOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,49 +60,49 @@ const ChatOverlay: React.FC<ChatOverlayProps> = ({
<>
{!open && (
<button
className="fixed bottom-6 right-6 bg-green-600 text-white rounded-full w-14 h-14 flex items-center justify-center shadow-lg hover:bg-green-700 transition-all z-50"
className="fixed bottom-6 right-6 bg-green-600 dark:bg-green-500 text-white rounded-full w-14 h-14 flex items-center justify-center shadow-lg hover:bg-green-700 dark:hover:bg-green-600 transition-all z-50"
onClick={() => setOpen(true)}
aria-label="Open chat"
>
💬
{unreadCount > 0 && (
<span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full w-6 h-6 flex items-center justify-center">
<span className="absolute -top-2 -right-2 bg-red-500 dark:bg-red-600 text-white text-xs rounded-full w-6 h-6 flex items-center justify-center">
{unreadCount > 9 ? "9+" : unreadCount}
</span>
)}
</button>
)}
{open && (
<div className="fixed bottom-6 right-6 w-80 max-w-[90vw] bg-white shadow-2xl rounded-xl flex flex-col z-50 animate-fade-in-up">
<div className="flex items-center justify-between p-4 border-b">
<span className="font-semibold">In-Call Chat - {roomId}</span>
<button onClick={() => setOpen(false)} className="text-gray-500 hover:text-red-600">
<div className="fixed bottom-6 right-6 w-80 max-w-[90vw] bg-white dark:bg-gray-900 shadow-2xl rounded-xl flex flex-col z-50 animate-fade-in-up border border-gray-200 dark:border-gray-800">
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-800">
<span className="font-semibold text-gray-900 dark:text-gray-100">In-Call Chat - {roomId}</span>
<button onClick={() => setOpen(false)} className="text-gray-500 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-500">
×
</button>
</div>
<div className="flex-1 overflow-y-auto p-4 space-y-2 h-72 bg-gray-50">
<div className="flex-1 overflow-y-auto p-4 space-y-2 h-72 bg-gray-50 dark:bg-gray-950">
{messages.map((msg, idx) => (
<div key={idx} className="flex flex-col">
<div className="flex items-center gap-2">
<span className="text-xs text-green-700 font-bold">{msg.user}</span>
<span className="text-xs text-gray-500">
<span className="text-xs text-green-700 dark:text-green-400 font-bold">{msg.user}</span>
<span className="text-xs text-gray-500 dark:text-gray-400">
{msg.time ? new Date(msg.time).toLocaleTimeString() : ""}
</span>
</div>
<span className="bg-green-100 text-gray-900 rounded px-2 py-1 text-sm w-fit max-w-[85%]">{msg.text}</span>
<span className="bg-green-100 dark:bg-green-900/30 text-gray-900 dark:text-gray-100 rounded px-2 py-1 text-sm w-fit max-w-[85%]">{msg.text}</span>
</div>
))}
<div ref={chatEndRef} />
</div>
<form className="flex items-center gap-2 p-3 border-t" onSubmit={sendMessage}>
<form className="flex items-center gap-2 p-3 border-t border-gray-200 dark:border-gray-800" onSubmit={sendMessage}>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
className="flex-1 rounded border px-2 py-1 text-sm focus:outline-none focus:ring focus:ring-green-400"
className="flex-1 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 px-2 py-1 text-sm focus:outline-none focus:ring focus:ring-green-400 dark:focus:ring-green-500"
/>
<button type="submit" className="bg-green-600 hover:bg-green-700 text-white px-4 py-1 rounded">
<button type="submit" className="bg-green-600 dark:bg-green-500 hover:bg-green-700 dark:hover:bg-green-600 text-white px-4 py-1 rounded">
Send
</button>
</form>
Expand Down
Loading
Loading