feat(web): header chip opens Account; drop Home footer
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 41s
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:
parent
6034da7153
commit
39651135b3
@ -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,22 +140,7 @@ 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
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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="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 />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user