Browse Source

feat(frontend): add embedded game iframe app

master
Stephanie Gredell 3 weeks ago
parent
commit
ce84848a25
  1. 10
      frontend/src/config/apps.ts
  2. 44
      frontend/src/pages/GameIframeApp.tsx
  3. 13
      frontend/src/pages/LandingPage.tsx

10
frontend/src/config/apps.ts

@ -5,6 +5,7 @@ const VideoApp = lazy(() => import('../pages/VideoApp').then(module => ({ defaul @@ -5,6 +5,7 @@ const VideoApp = lazy(() => import('../pages/VideoApp').then(module => ({ defaul
const SpeechSoundsApp = lazy(() => import('../pages/SpeechSoundsApp').then(module => ({ default: module.SpeechSoundsApp })));
const TicTacToeApp = lazy(() => import('../pages/TicTacToeApp').then(module => ({ default: module.TicTacToeApp })));
const DrawingPadApp = lazy(() => import('../pages/DrawingPadApp').then(module => ({ default: module.DrawingPadApp })));
const GameIframeApp = lazy(() => import('../pages/GameIframeApp').then(module => ({ default: module.GameIframeApp })));
export type App = {
id: string;
@ -52,5 +53,14 @@ export const APPS: App[] = [ @@ -52,5 +53,14 @@ export const APPS: App[] = [
link: '/drawing-pad',
disabled: false,
component: DrawingPadApp
},
{
id: 'iframegame',
name: 'Embedded Game',
description: 'Launch an external game without leaving Kiddos.',
cta: 'Open Game',
link: '/embedded-game',
disabled: false,
component: GameIframeApp
}
];

44
frontend/src/pages/GameIframeApp.tsx

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
import { useState } from 'react';
const IFRAME_URL = 'https://www.google.com';
export function GameIframeApp() {
const [loading, setLoading] = useState(true);
return (
<div className="min-h-screen bg-background px-4 py-8">
<div className="max-w-5xl mx-auto space-y-6">
<header className="text-center space-y-2">
<p className="text-sm uppercase tracking-widest text-muted-foreground">Arcade Corner</p>
<h1 className="text-4xl font-bold text-primary">Embedded Game View</h1>
<p className="text-muted-foreground">
Enjoy a game inside Kiddos while keeping all of our safety tools and controls handy.
</p>
</header>
<div className="bg-card border border-border rounded-3xl shadow-2xl overflow-hidden">
{loading && (
<div className="p-4 text-center text-muted-foreground text-sm bg-muted">
Loading embedded game...
</div>
)}
<iframe
src={IFRAME_URL}
title="Embedded Game"
className="w-full min-h-[75vh] border-0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
allowFullScreen
onLoad={() => setLoading(false)}
/>
</div>
<div className="text-center text-xs text-muted-foreground">
Content below is provided by an external site. Replace the URL in `GameIframeApp.tsx` when your game is ready.
</div>
</div>
</div>
);
}

13
frontend/src/pages/LandingPage.tsx

@ -9,6 +9,8 @@ const categoryEmojis: { [key: string]: string } = { @@ -9,6 +9,8 @@ const categoryEmojis: { [key: string]: string } = {
videos: '📺',
speechsounds: '🗣',
tictactoe: '⭕',
drawingpad: '🎨',
iframegame: '🕹',
all: '🎮',
};
@ -17,6 +19,7 @@ const categoryColors: { [key: string]: string } = { @@ -17,6 +19,7 @@ const categoryColors: { [key: string]: string } = {
speechsounds: 'purple',
tictactoe: 'blue',
drawingpad: 'amber',
iframegame: 'green',
};
const colorMap: { [key: string]: string } = {
@ -118,6 +121,16 @@ export function LandingPage() { @@ -118,6 +121,16 @@ export function LandingPage() {
fetchPriority="auto"
disableWebP={true}
/>
) : app.id === 'iframegame' ? (
<OptimizedImage
src="/magic-wand.png"
alt="Embedded Game"
className="w-20 h-20 object-contain"
width={80}
height={80}
loading="eager"
fetchPriority="auto"
/>
) : (
<span className="text-5xl">{emoji}</span>
)}

Loading…
Cancel
Save