Skip to content

Commit 63f7fee

Browse files
committed
Different Layout
1 parent 02f08fa commit 63f7fee

File tree

14 files changed

+1009
-22
lines changed

14 files changed

+1009
-22
lines changed

Tests/ResponsiveLayoutTests.cs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using Microsoft.AspNetCore.Components;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Bunit;
4+
using TomAndJerry.Layout;
5+
using TomAndJerry.Services;
6+
using TomAndJerry.Component;
7+
8+
namespace TomAndJerry.Tests
9+
{
10+
public class ResponsiveLayoutTests : UITestBase
11+
{
12+
[Test]
13+
public async Task MainLayout_ShouldRenderMobileLayout_WhenScreenIsMobile()
14+
{
15+
// Arrange
16+
var responsiveService = Services.GetRequiredService<IResponsiveService>();
17+
18+
// Mock mobile screen size
19+
await responsiveService.InitializeAsync();
20+
21+
// Act
22+
var component = RenderComponent<MainLayout>(parameters => parameters
23+
.Add(p => p.Body, (RenderFragment)((builder) =>
24+
{
25+
builder.AddMarkupContent(0, "<div>Test Content</div>");
26+
}))
27+
);
28+
29+
// Assert
30+
// The component should render without errors
31+
Assert.That(component, Is.Not.Null);
32+
}
33+
34+
[Test]
35+
public async Task MainLayout_ShouldRenderTabletLayout_WhenScreenIsTablet()
36+
{
37+
// Arrange
38+
var responsiveService = Services.GetRequiredService<IResponsiveService>();
39+
40+
// Mock tablet screen size
41+
await responsiveService.InitializeAsync();
42+
43+
// Act
44+
var component = RenderComponent<MainLayout>(parameters => parameters
45+
.Add(p => p.Body, (RenderFragment)((builder) =>
46+
{
47+
builder.AddMarkupContent(0, "<div>Test Content</div>");
48+
}))
49+
);
50+
51+
// Assert
52+
// The component should render without errors
53+
Assert.That(component, Is.Not.Null);
54+
}
55+
56+
[Test]
57+
public async Task MainLayout_ShouldRenderDesktopLayout_WhenScreenIsDesktop()
58+
{
59+
// Arrange
60+
var responsiveService = Services.GetRequiredService<IResponsiveService>();
61+
62+
// Mock desktop screen size
63+
await responsiveService.InitializeAsync();
64+
65+
// Act
66+
var component = RenderComponent<MainLayout>(parameters => parameters
67+
.Add(p => p.Body, (RenderFragment)((builder) =>
68+
{
69+
builder.AddMarkupContent(0, "<div>Test Content</div>");
70+
}))
71+
);
72+
73+
// Assert
74+
// The component should render without errors
75+
Assert.That(component, Is.Not.Null);
76+
}
77+
78+
[Test]
79+
public void MobileAppBar_ShouldRenderCorrectly()
80+
{
81+
// Act
82+
var component = RenderComponent<MobileAppBar>();
83+
84+
// Assert
85+
Assert.That(component, Is.Not.Null);
86+
var header = component.Find("#mobile-app-header");
87+
Assert.That(header, Is.Not.Null);
88+
}
89+
90+
[Test]
91+
public void MobileFooter_ShouldRenderCorrectly()
92+
{
93+
// Act
94+
var component = RenderComponent<MobileFooter>();
95+
96+
// Assert
97+
Assert.That(component, Is.Not.Null);
98+
var footer = component.Find(".tom-jerry-footer");
99+
Assert.That(footer, Is.Not.Null);
100+
}
101+
102+
[Test]
103+
public void TabletAppBar_ShouldRenderCorrectly()
104+
{
105+
// Act
106+
var component = RenderComponent<TabletAppBar>();
107+
108+
// Assert
109+
Assert.That(component, Is.Not.Null);
110+
var header = component.Find("#tablet-app-header");
111+
Assert.That(header, Is.Not.Null);
112+
}
113+
114+
[Test]
115+
public void TabletFooter_ShouldRenderCorrectly()
116+
{
117+
// Act
118+
var component = RenderComponent<TabletFooter>();
119+
120+
// Assert
121+
Assert.That(component, Is.Not.Null);
122+
var footer = component.Find(".tom-jerry-footer");
123+
Assert.That(footer, Is.Not.Null);
124+
}
125+
}
126+
}

src/Component/MobileAppBar.razor

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
@using TomAndJerry.Services
2+
@using TomAndJerry.Model
3+
@inject IStateService StateService
4+
@inject NavigationManager nav
5+
@inject IJSRuntime JSRuntime
6+
7+
<header id="mobile-app-header" class="fixed top-0 left-0 right-0 z-50 tom-jerry-header shadow-lg">
8+
<div class="max-w-7xl mx-auto px-2">
9+
<div class="flex items-center justify-between h-14">
10+
<!-- Left Section - Logo -->
11+
<div id="mobile-header-left-section" class="flex items-center space-x-2">
12+
<div id="mobile-app-logo" class="flex items-center space-x-2 cursor-pointer" @onclick="GoToHomePage">
13+
<div class="tom-character">
14+
<div class="w-8 h-8 rounded-full overflow-hidden ring-2 ring-white/30 shadow-lg">
15+
<RandomSticker Category="classic" CssClass="w-full h-full" ImageCssClass="w-full h-full object-cover" AutoRefresh="true" RefreshIntervalSeconds="12" />
16+
</div>
17+
</div>
18+
</div>
19+
</div>
20+
21+
<!-- Center Section - Search (Compact) -->
22+
<div id="mobile-header-search-section" class="flex-1 max-w-xs mx-2">
23+
<RealTimeSearch />
24+
</div>
25+
26+
<!-- Right Section - Mobile Menu -->
27+
<div id="mobile-header-right-section" class="flex items-center space-x-1">
28+
<!-- Mobile Menu Button -->
29+
<button id="mobile-menu-btn" @onclick="ToggleMobileMenu"
30+
class="flex items-center justify-center w-10 h-10 bg-cartoon-yellow text-amber-800 rounded-xl font-bold font-comic hover:bg-cartoon-orange transition-colors cartoon-rounded">
31+
<span class="text-lg">☰</span>
32+
</button>
33+
</div>
34+
</div>
35+
36+
<!-- Mobile Menu Dropdown -->
37+
@if (isMobileMenuOpen)
38+
{
39+
<div class="mobile-menu-dropdown bg-white/95 backdrop-blur-md border-t border-white/20 shadow-lg">
40+
<div class="px-4 py-3 space-y-2">
41+
<button @onclick="GoToHomePage"
42+
class="w-full flex items-center space-x-3 text-slate-800 hover:text-slate-900 transition-colors font-comic text-base p-2 rounded-lg hover:bg-white/20">
43+
<span class="text-xl">🎬</span>
44+
<span>All Episodes</span>
45+
</button>
46+
<button @onclick="GoToStickers"
47+
class="w-full flex items-center space-x-3 text-slate-800 hover:text-slate-900 transition-colors font-comic text-base p-2 rounded-lg hover:bg-white/20">
48+
<span class="text-xl">🎭</span>
49+
<span>Sticker Gallery</span>
50+
</button>
51+
<button @onclick="GoToSearch"
52+
class="w-full flex items-center space-x-3 text-slate-800 hover:text-slate-900 transition-colors font-comic text-base p-2 rounded-lg hover:bg-white/20">
53+
<span class="text-xl">🔍</span>
54+
<span>Search Episodes</span>
55+
</button>
56+
<button @onclick="GoToQuiz"
57+
class="w-full flex items-center space-x-3 text-slate-800 hover:text-slate-900 transition-colors font-comic text-base p-2 rounded-lg hover:bg-white/20">
58+
<span class="text-xl">🧠</span>
59+
<span>Quiz</span>
60+
</button>
61+
</div>
62+
</div>
63+
}
64+
</div>
65+
</header>
66+
67+
@code {
68+
private bool isMobileMenuOpen = false;
69+
70+
void GoToHomePage()
71+
{
72+
nav.NavigateTo("");
73+
CloseMobileMenu();
74+
}
75+
76+
void GoToStickers()
77+
{
78+
nav.NavigateTo("stickers");
79+
CloseMobileMenu();
80+
}
81+
82+
void GoToSearch()
83+
{
84+
nav.NavigateTo("Search/");
85+
CloseMobileMenu();
86+
}
87+
88+
void GoToQuiz()
89+
{
90+
nav.NavigateTo("quiz");
91+
CloseMobileMenu();
92+
}
93+
94+
void ToggleMobileMenu()
95+
{
96+
isMobileMenuOpen = !isMobileMenuOpen;
97+
}
98+
99+
void CloseMobileMenu()
100+
{
101+
isMobileMenuOpen = false;
102+
}
103+
104+
protected override void OnInitialized()
105+
{
106+
StateService.OnStateChanged += StateHasChanged;
107+
}
108+
109+
public void Dispose()
110+
{
111+
StateService.OnStateChanged -= StateHasChanged;
112+
}
113+
}

0 commit comments

Comments
 (0)