feat(auth): update sidebar for authentication status and improve user guidance
This commit is contained in:
parent
6f8d8b8af0
commit
6267753aec
@ -37,9 +37,6 @@ export default function App() {
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<Link to="/" className="brand">Watch Party</Link>
|
<Link to="/" className="brand">Watch Party</Link>
|
||||||
<div className="auth-slot">
|
|
||||||
<AuthStatus />
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
{/* Time sync banner (checks every 5 min; shows if |skew| > 500ms) */}
|
{/* Time sync banner (checks every 5 min; shows if |skew| > 500ms) */}
|
||||||
<TimeSyncNotice thresholdMs={TIME_SYNC_OFF_THRESHOLD} lang="ja" />
|
<TimeSyncNotice thresholdMs={TIME_SYNC_OFF_THRESHOLD} lang="ja" />
|
||||||
@ -50,6 +47,11 @@ export default function App() {
|
|||||||
<NavLink end to="/" className="navlink">Timer</NavLink>
|
<NavLink end to="/" className="navlink">Timer</NavLink>
|
||||||
<NavLink to="/shows" className="navlink">Shows</NavLink>
|
<NavLink to="/shows" className="navlink">Shows</NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
|
<div className="sidebar-auth">
|
||||||
|
<div className="sidebar-auth-title">管理用サインイン</div>
|
||||||
|
<div className="sidebar-auth-note">削除や管理にはログインが必要です。</div>
|
||||||
|
<AuthStatus />
|
||||||
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{/* Backdrop for overlap mode or to close on click */}
|
{/* Backdrop for overlap mode or to close on click */}
|
||||||
|
|||||||
@ -177,13 +177,10 @@ kbd {
|
|||||||
z-index: 50;
|
z-index: 50;
|
||||||
top: 0; left: 16px; right: 16px;
|
top: 0; left: 16px; right: 16px;
|
||||||
height: var(--header-h);
|
height: var(--header-h);
|
||||||
|
display: flex;
|
||||||
/* three areas: banner (fills), burger (left), title (left of center) */
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto 1fr; /* burger | title | banner */
|
|
||||||
grid-template-areas: "burger title banner";
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
column-gap: 12px;
|
gap: 12px;
|
||||||
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -194,11 +191,6 @@ kbd {
|
|||||||
letter-spacing: 0.2px;
|
letter-spacing: 0.2px;
|
||||||
text-shadow: 0 1px 10px rgba(0,0,0,0.25);
|
text-shadow: 0 1px 10px rgba(0,0,0,0.25);
|
||||||
}
|
}
|
||||||
.auth-slot {
|
|
||||||
grid-area: banner;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
.auth-chip {
|
.auth-chip {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -266,8 +258,9 @@ kbd {
|
|||||||
border-right: 1px solid rgba(255,255,255,0.12);
|
border-right: 1px solid rgba(255,255,255,0.12);
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
transition: transform 180ms ease;
|
transition: transform 180ms ease;
|
||||||
display: grid;
|
display: flex;
|
||||||
align-content: start;
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
padding: 70px 16px 16px; /* leave space under header */
|
padding: 70px 16px 16px; /* leave space under header */
|
||||||
}
|
}
|
||||||
.sidebar.open { transform: translateX(0); }
|
.sidebar.open { transform: translateX(0); }
|
||||||
@ -287,6 +280,32 @@ kbd {
|
|||||||
}
|
}
|
||||||
.navlink.active { color: var(--accent); border-color: rgba(121,192,255,0.6); }
|
.navlink.active { color: var(--accent); border-color: rgba(121,192,255,0.6); }
|
||||||
|
|
||||||
|
.sidebar-auth {
|
||||||
|
margin-top: auto;
|
||||||
|
padding-top: 12px;
|
||||||
|
border-top: 1px solid rgba(255,255,255,0.12);
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.sidebar-auth-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.sidebar-auth-note {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--subtle);
|
||||||
|
}
|
||||||
|
.sidebar-auth .auth-btn {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.sidebar-auth .auth-chip {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Backdrop (for overlap mode, also clickable to close) */
|
/* Backdrop (for overlap mode, also clickable to close) */
|
||||||
.backdrop {
|
.backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -616,7 +635,7 @@ kbd {
|
|||||||
.debug-overlay {
|
.debug-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 16px;
|
bottom: 16px;
|
||||||
left: 16px;
|
right: 16px;
|
||||||
z-index: 190;
|
z-index: 190;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ export default function ShowsPage() {
|
|||||||
const redirectTid = useRef<number | null>(null);
|
const redirectTid = useRef<number | null>(null);
|
||||||
const isRedirecting = redirectIn !== null;
|
const isRedirecting = redirectIn !== null;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { enabled: authEnabled, idToken, backendClaims, verifying, signInWithGoogle } = useAuth();
|
const { enabled: authEnabled, idToken, backendClaims, verifying } = useAuth();
|
||||||
const isAuthed = authEnabled && !!idToken;
|
const isAuthed = authEnabled && !!idToken;
|
||||||
|
|
||||||
// フォーム状態
|
// フォーム状態
|
||||||
@ -314,17 +314,10 @@ export default function ShowsPage() {
|
|||||||
<div className="subtle" style={{ marginTop: 0, display: "flex", flexDirection: "column", gap: 4 }}>
|
<div className="subtle" style={{ marginTop: 0, display: "flex", flexDirection: "column", gap: 4 }}>
|
||||||
<span>エピソードを選び、必要に応じて開始時刻(HH:MM)を入力し、「現在のエピソードに設定」を押してください。</span>
|
<span>エピソードを選び、必要に応じて開始時刻(HH:MM)を入力し、「現在のエピソードに設定」を押してください。</span>
|
||||||
<span>
|
<span>
|
||||||
削除は認証後のみ実行できます。
|
削除は認証後のみ実行できます。サイドバー下部の「管理用サインイン」からログインしてください。
|
||||||
{!isAuthed && (
|
|
||||||
<>
|
|
||||||
{" "} <button className="link-btn" onClick={() => signInWithGoogle().catch(() => {})}>
|
|
||||||
Googleでサインイン
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isAuthed && (
|
{isAuthed && (
|
||||||
<span style={{ color: backendClaims ? "#6de3a2" : "#f0d000" }}>
|
<span style={{ color: backendClaims ? "#6de3a2" : "#f0d000" }}>
|
||||||
{verifying ? "トークン確認中…" : backendClaims ? "バックエンドで確認済み" : "未確認トークン"}
|
{" "} {verifying ? "トークン確認中…" : backendClaims ? "バックエンドで確認済み" : "未確認トークン"}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user