hy2-panel/app/me/page.tsx

167 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { getRequestOrigin } from "@/lib/request-origin";
import { buildSubscriptionUrl, describeRemainingTraffic } from "@/lib/subscription";
import { requireUserSession } from "@/lib/session";
import { formatBytes, getUserById } from "@/lib/store";
export const metadata: Metadata = {
title: "我的订阅",
};
export default async function MePage() {
const session = await requireUserSession();
const [user, origin] = await Promise.all([
getUserById(session.user_id),
getRequestOrigin(),
]);
if (!user) {
redirect("/login");
}
const usedBytes = user.used_tx_bytes + user.used_rx_bytes;
const subscriptionUrl = user.subscription_token
? buildSubscriptionUrl(user.subscription_token, origin)
: null;
const clashImportUrl = subscriptionUrl
? `clash://install-config?url=${encodeURIComponent(subscriptionUrl)}`
: null;
return (
<main className="me-shell">
<div aria-hidden="true" className="me-backdrop">
<span className="me-glow me-glow--warm" />
<span className="me-glow me-glow--cool" />
<span className="me-glow me-glow--light" />
</div>
<section className="me-stage">
<article className="me-panel me-hero">
<div className="me-hero-copy">
<span className="eyebrow">FEIEPROXY SELF SERVICE</span>
<h1>{user.username}</h1>
<p className="page-lede">
FeieProxy
Clash URL Scheme
</p>
<div className="badge-row">
<span
className={`status-pill ${
user.enabled ? "status-pill--ok" : "status-pill--danger"
}`}
>
{user.enabled ? "账号已启用" : "账号已禁用"}
</span>
<span className="status-pill status-pill--neutral">
{user.expires_at ?? "长期有效"}
</span>
<span className="status-pill status-pill--warm">
{describeRemainingTraffic(user)}
</span>
</div>
</div>
<div className="me-identity-card">
<span className="feature-kicker">ACCOUNT SNAPSHOT</span>
<strong className="mono break-all">{user.auth_id}</strong>
<p className="muted">
{user.subscription_label || user.username}
</p>
</div>
</article>
<section className="me-grid">
<article className="me-panel me-subscription-card">
<div className="section-title section-title--top">
<div>
<span className="feature-kicker">SUBSCRIPTION</span>
<h2></h2>
</div>
<span className="status-pill status-pill--ink">Clash / Mihomo</span>
</div>
<p className="muted">
`clash://`
</p>
<div className="me-action-row">
{clashImportUrl ? (
<a className="primary-button me-action-button" href={clashImportUrl}>
Clash
</a>
) : (
<span className="status-pill status-pill--off"></span>
)}
{subscriptionUrl ? (
<a
className="ghost-button me-action-button"
href={subscriptionUrl}
target="_blank"
rel="noreferrer"
>
</a>
) : null}
</div>
<div className="me-link-card">
<span className="feature-kicker">SUBSCRIPTION URL</span>
<p className="mono break-all">{subscriptionUrl ?? "暂不可用"}</p>
</div>
<div className="me-tip-grid">
<div className="me-tip-card">
<span className="feature-kicker">TIP 01</span>
<strong></strong>
<p className="muted"> `clash://` </p>
</div>
<div className="me-tip-card">
<span className="feature-kicker">TIP 02</span>
<strong></strong>
<p className="muted"> Clash / Mihomo </p>
</div>
</div>
</article>
<div className="me-side-stack">
<article className="me-panel">
<div className="section-title">
<h2></h2>
</div>
<div className="me-metrics-grid">
<div className="me-metric-card me-metric-card--paper">
<span></span>
<strong>{formatBytes(usedBytes)}</strong>
</div>
<div className="me-metric-card me-metric-card--warm">
<span></span>
<strong>{describeRemainingTraffic(user)}</strong>
</div>
<div className="me-metric-card me-metric-card--ink">
<span></span>
<strong>{formatBytes(user.used_tx_bytes)}</strong>
</div>
<div className="me-metric-card me-metric-card--sage">
<span></span>
<strong>{formatBytes(user.used_rx_bytes)}</strong>
</div>
</div>
</article>
<article className="me-panel me-support-card">
<span className="feature-kicker">ACCESS</span>
<h2>使</h2>
<ul className="me-note-list">
<li></li>
<li>使 `IP:3000` </li>
<li></li>
</ul>
<form action="/logout" method="post">
<button className="ghost-button me-action-button me-action-button--full" type="submit">
退
</button>
</form>
</article>
</div>
</section>
</section>
</main>
);
}