Skip to content

Commit 3bb7b81

Browse files
Sora4431claude
andauthored
feat(ui): [Phase 4] UI を整える — /profile /users /users/:username のデザイン統一 (SOR-12) (#171)
* feat(ui): /profile /users /users/:username のデザインを / に統一 (SOR-12) - / のヒーローセクション右上に「みんなのしおり」「ログイン/マイページ」ナビボタンを追加 - /profile, /users, /users/[username] をグラデーション背景 + 丸角白パネルで統一 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ui): ログイン状態をナビゲーション後に再チェック + アクセシビリティ改善 - afterNavigate で loggedIn を再評価 (SPA遷移後のズレ解消) - hero-nav に aria-label 追加 - モバイル (max-width: 480px) のナビボタンサイズ調整 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(ui): PageShell コンポーネントで共通レイアウトを一元管理 - PageShell.svelte を新規作成し、グラデーションヘッダー + 白パネルCSSを集約 - /profile, /users, /users/:username の重複CSSを PageShell に置き換え - refreshLoggedIn() 関数で loggedIn 更新ロジックを一箇所に集約 Copilot レビューコメントへの対応 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 83028f4 commit 3bb7b81

5 files changed

Lines changed: 504 additions & 343 deletions

File tree

apps/web/src/lib/PageShell.svelte

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<script lang="ts">
2+
import type { Snippet } from "svelte";
3+
4+
let {
5+
title,
6+
subtitle,
7+
backHref = "/",
8+
backLabel = "← たびたび",
9+
children,
10+
}: {
11+
title: string;
12+
subtitle?: string;
13+
backHref?: string;
14+
backLabel?: string;
15+
children: Snippet;
16+
} = $props();
17+
</script>
18+
19+
<div class="page-wrapper">
20+
<header class="page-header">
21+
<div class="header-inner">
22+
<a href={backHref} class="back-link">{backLabel}</a>
23+
<h1 class="page-title">{title}</h1>
24+
{#if subtitle}
25+
<p class="page-subtitle">{subtitle}</p>
26+
{/if}
27+
</div>
28+
</header>
29+
30+
<div class="page-content">
31+
<div class="content-inner">
32+
{@render children()}
33+
</div>
34+
</div>
35+
</div>
36+
37+
<style>
38+
.page-wrapper {
39+
min-height: 100vh;
40+
background: linear-gradient(145deg, #84c6ff 0%, #a6b3ff 40%, #b5daf8 100%);
41+
}
42+
43+
.page-header {
44+
padding: 1.5rem 1rem 3rem;
45+
}
46+
47+
.header-inner {
48+
max-width: 768px;
49+
margin: 0 auto;
50+
}
51+
52+
.back-link {
53+
display: inline-flex;
54+
align-items: center;
55+
color: rgba(255, 255, 255, 0.85);
56+
font-size: 0.875rem;
57+
font-weight: 600;
58+
text-decoration: none;
59+
margin-bottom: 1rem;
60+
transition: color 0.15s;
61+
}
62+
63+
.back-link:hover {
64+
color: white;
65+
}
66+
67+
.page-title {
68+
font-size: 2rem;
69+
font-weight: 900;
70+
color: white;
71+
margin: 0;
72+
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
73+
}
74+
75+
.page-subtitle {
76+
font-size: 0.9rem;
77+
color: rgba(255, 255, 255, 0.85);
78+
margin: 0.25rem 0 0;
79+
}
80+
81+
.page-content {
82+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.93) 0%, #f7fbff 100%);
83+
border-radius: 1.5rem 1.5rem 0 0;
84+
min-height: calc(100vh - 11rem);
85+
padding: 2rem 1rem 3rem;
86+
}
87+
88+
.content-inner {
89+
max-width: 768px;
90+
margin: 0 auto;
91+
}
92+
</style>

apps/web/src/routes/+page.svelte

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
22
import { onMount } from "svelte";
3+
import { afterNavigate } from "$app/navigation";
34
import { auth } from "$lib/auth";
5+
import { userAuth } from "$lib/user-auth";
46
import { resetDemoMode } from "$lib/demo";
57
import {
68
PreviewCarousel,
@@ -25,6 +27,12 @@
2527
IconExternalLink,
2628
} from "./home/icons";
2729
30+
let loggedIn = $state(false);
31+
32+
function refreshLoggedIn() {
33+
loggedIn = userAuth.isLoggedIn();
34+
}
35+
2836
let recentItineraries = $state<
2937
Array<{ id: string; title: string; visitedAt: number }>
3038
>([]);
@@ -64,8 +72,11 @@
6472
};
6573
}
6674
75+
afterNavigate(refreshLoggedIn);
76+
6777
onMount(() => {
6878
resetDemoMode();
79+
refreshLoggedIn();
6980
7081
recentItineraries = auth.getRecentItineraries();
7182
showRecent = true;
@@ -134,6 +145,13 @@
134145
{/each}
135146

136147
<section class="hero" class:hero-hidden={heroHidden}>
148+
<nav class="hero-nav" aria-label="サイトナビゲーション">
149+
<a href="/users" class="nav-users-btn">みんなのしおり</a>
150+
<a href="/profile" class="nav-profile-btn">
151+
{loggedIn ? "マイページ" : "ログイン"}
152+
</a>
153+
</nav>
154+
137155
<div class="hero-bg-decoration">
138156
<div class="bg-circle bg-circle-1"></div>
139157
<div class="bg-circle bg-circle-2"></div>
@@ -771,6 +789,67 @@
771789
}
772790
}
773791
792+
.hero-nav {
793+
position: absolute;
794+
top: 1.25rem;
795+
right: 1.5rem;
796+
display: flex;
797+
gap: 0.5rem;
798+
align-items: center;
799+
z-index: 10;
800+
}
801+
802+
.nav-users-btn {
803+
color: rgba(255, 255, 255, 0.9);
804+
font-size: 0.85rem;
805+
font-weight: 600;
806+
padding: 0.4rem 0.75rem;
807+
border-radius: 9999px;
808+
text-decoration: none;
809+
transition: background 0.15s;
810+
}
811+
812+
.nav-users-btn:hover {
813+
background: rgba(255, 255, 255, 0.2);
814+
}
815+
816+
.nav-profile-btn {
817+
background: rgba(255, 255, 255, 0.95);
818+
color: #3d5a99;
819+
font-size: 0.85rem;
820+
font-weight: 700;
821+
padding: 0.4rem 1rem;
822+
border-radius: 9999px;
823+
text-decoration: none;
824+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
825+
transition:
826+
background 0.15s,
827+
box-shadow 0.15s;
828+
}
829+
830+
.nav-profile-btn:hover {
831+
background: white;
832+
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.18);
833+
}
834+
835+
@media (max-width: 480px) {
836+
.hero-nav {
837+
top: 0.75rem;
838+
right: 0.75rem;
839+
gap: 0.25rem;
840+
}
841+
842+
.nav-users-btn {
843+
font-size: 0.78rem;
844+
padding: 0.35rem 0.6rem;
845+
}
846+
847+
.nav-profile-btn {
848+
font-size: 0.78rem;
849+
padding: 0.35rem 0.75rem;
850+
}
851+
}
852+
774853
@media (prefers-reduced-motion: reduce) {
775854
.animate-slide-up {
776855
animation: none !important;

0 commit comments

Comments
 (0)