feat(web): header chip opens Account; drop Home footer
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 41s

Top-right DeviceChip now navigates to /settings — same destination as
the old footer "Account" link, one less piece of chrome. Pricing stays
reachable from the Account page via the existing "Compare" link in the
Free plan panel. Profile editing moves into the Account section so the
capability isn't lost when the chip stops opening the edit modal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
ordinarthur 2026-04-20 16:28:03 +02:00
parent 6034da7153
commit 39651135b3
2 changed files with 43 additions and 30 deletions

View File

@ -1,4 +1,4 @@
import { useCallback, useState } from "react";
import { useCallback } from "react";
import { Link } from "react-router-dom";
import { useSignaling } from "../hooks/useSignaling";
import { useStore } from "../stores/useStore";
@ -27,7 +27,6 @@ function HomeConnected() {
const setError = useStore((s) => s.setError);
const { deviceName, avatar } = useProfileStore();
const [showProfileEdit, setShowProfileEdit] = useState(false);
const selectedPeer = peers.find((p) => p.peerId === selectedPeerId) ?? null;
@ -87,11 +86,7 @@ function HomeConnected() {
Peer to peer · Encrypted
</p>
</div>
<DeviceChip
name={deviceName}
avatar={avatar}
onEdit={() => setShowProfileEdit(true)}
/>
<DeviceChip name={deviceName} avatar={avatar} />
</header>
{error && (
@ -145,23 +140,8 @@ function HomeConnected() {
</div>
</section>
<footer className="pt-6 mt-10 sm:pt-8 sm:mt-14 rule flex items-center justify-between text-xs text-ink-muted">
<span>Nothing transits the server</span>
<div className="flex items-center gap-4">
<Link to="/pricing" className="text-ink-muted hover:text-ink transition-colors duration-fast">
Pricing
</Link>
<Link to="/settings" className="text-ink hover:text-signal transition-colors duration-fast">
Account
</Link>
</div>
</footer>
</div>
{showProfileEdit && (
<ProfileSetup isEditing onDone={() => setShowProfileEdit(false)} />
)}
{incomingRequest && (
<ReceiveDialog
request={incomingRequest}
@ -176,15 +156,14 @@ function HomeConnected() {
function DeviceChip({
name,
avatar,
onEdit,
}: {
name: string;
avatar: string | null;
onEdit: () => void;
}) {
return (
<button
onClick={onEdit}
<Link
to="/settings"
aria-label="Account"
className="group shrink-0 flex items-center gap-2 px-2.5 py-1.5 border border-paper-edge
hover:border-ink transition-colors duration-fast ease-crisp
bg-paper rounded-sm"
@ -206,7 +185,7 @@ function DeviceChip({
<span className="text-xs sm:text-sm text-ink truncate max-w-[80px] sm:max-w-[120px]">
{name}
</span>
</button>
</Link>
);
}

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import { Link, useSearchParams } from "react-router-dom";
import { useAuthStore } from "../stores/useAuthStore";
import { useProfileStore } from "../stores/useProfileStore";
import ProfileSetup from "../components/ProfileSetup";
import {
deleteTransfer,
listInboxTransfers,
@ -29,6 +30,7 @@ export default function Settings() {
const [searchParams] = useSearchParams();
const signedIn = searchParams.get("signed_in") === "1";
const error = searchParams.get("error");
const [editingProfile, setEditingProfile] = useState(false);
useEffect(() => {
loadUser();
@ -79,12 +81,44 @@ export default function Settings() {
<h2 className="font-display text-2xl text-ink mt-2 mb-5 tracking-tight">
Your identity
</h2>
<div className="paper-panel px-5 py-4">
<div className="text-xs uppercase tracking-[0.15em] text-ink-muted">Email</div>
<div className="text-ink mt-1">{user.email}</div>
<div className="paper-panel px-5 py-4 space-y-4">
<div>
<div className="text-xs uppercase tracking-[0.15em] text-ink-muted">Email</div>
<div className="text-ink mt-1">{user.email}</div>
</div>
<div className="pt-4 border-t border-paper-edge flex items-center gap-3">
{profile.avatar ? (
<img
src={profile.avatar}
alt=""
className="w-10 h-10 rounded-full object-cover border border-paper-edge"
/>
) : (
<span className="w-10 h-10 rounded-full bg-paper-deep border border-paper-edge
flex items-center justify-center text-xs text-ink-muted">
</span>
)}
<div className="min-w-0 flex-1">
<div className="text-xs uppercase tracking-[0.15em] text-ink-muted">
This device
</div>
<div className="text-ink mt-0.5 truncate">{profile.deviceName}</div>
</div>
<button
onClick={() => setEditingProfile(true)}
className="shrink-0 text-xs text-ink-muted hover:text-ink transition-colors"
>
Edit
</button>
</div>
</div>
</section>
{editingProfile && (
<ProfileSetup isEditing onDone={() => setEditingProfile(false)} />
)}
<PlanSection />
<ReceivedSection />