修复很多问题

This commit is contained in:
海龙 2025-08-29 06:45:11 +08:00
parent 5b268abe5e
commit a259d66f7c
5 changed files with 144 additions and 100 deletions

View File

@ -26,7 +26,6 @@ export default function RootLayout({
}) {
const [showCallbackModal, setShowCallbackModal] = useState(false)
const openCallback = async function (ev: MessageEvent<any>) {
console.log(ev)
if (ev.data.type === 'waiting-payment') {
setShowCallbackModal(true)
}

View File

@ -15,8 +15,39 @@ import { fetchSubscriptionPlans, SubscriptionPlan } from "@/lib/stripe";
export default function PricingPage() {
useEffect(() => {
// 获取当前窗口尺寸
const currentWidth = window.innerWidth;
const currentHeight = window.innerHeight;
// 计算缩放比例 (1920x1080)
const wScale = currentWidth / 1920;
const hScale = currentHeight / 1080;
// 检查app节点是否存在
const pricingPage = document.getElementById("pricing-page");
if (!pricingPage) {
console.error("未找到app节点");
return;
}
// setHPading((hScale || 1) * 10);
// 创建样式元素
const style = document.createElement("style");
// 设置CSS样式
style.textContent = `
#pricing-page {
transform-origin: top left;
transform: scale(${wScale}, ${hScale});
width: 1920px;
height: 1080px;
}
`;
// 将样式添加到head
document.head.appendChild(style);
}, []);
return (
<div className="w-full h-full overflow-y-auto bg-black text-white pb-[10rem]">
<div className="w-full h-full overflow-y-auto bg-black text-white pb-[10rem]" id="pricing-page">
{/* Main Content */}
<HomeModule5 />
</div>
@ -66,7 +97,7 @@ function HomeModule5() {
}, [plans, billingType]);
const handleSubscribe = async (planName: string) => {
if (planName === "hobby") {
if (planName === "Kickoff") {
return;
}
@ -103,14 +134,14 @@ function HomeModule5() {
return (
<div
data-alt="core-value-section"
className="home-module5 h-[1600px] relative flex flex-col items-center justify-center w-full bg-black snap-start"
className="home-module5 h-[1300px] relative flex flex-col items-center justify-center w-full bg-black snap-start"
>
<div
data-alt="core-value-content"
className="center z-10 flex flex-col items-center mb-[8rem]"
className="center z-10 flex flex-col items-center mb-[4rem]"
>
<h2 className="text-white text-[3.375rem] leading-[100%] font-normal mb-[1.5rem]">
Start Creating
Pick a plan and make it yours
</h2>
{/* 计费切换 */}
@ -133,7 +164,7 @@ function HomeModule5() {
: "text-white hover:text-gray-300"
}`}
>
Yearly - <span className="text-[#FFCC6D]">10%</span>
Yearly - <span className="text-[#FFCC6D]">20%</span>
</button>
</div>
</div>
@ -143,7 +174,7 @@ function HomeModule5() {
{pricingPlans.map((plan, index) => (
<div
key={index}
className=" w-[26rem] h-[38.125rem] bg-black rounded-lg p-[1.5rem] border border-white/20"
className=" w-[24rem] h-[38.125rem] bg-black rounded-lg p-[1.5rem] border border-white/20"
>
<h3 className="text-white text-2xl font-normal mb-[1rem]">
{plan.title}

View File

@ -714,7 +714,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
{!isExpanded && (
<div className="absolute top-2 right-2 z-10 flex items-center">
{/* 使用 Dropdown 替代手动控制显示/隐藏 */}
<Dropdown
{/* <Dropdown
open={showConfigOptions}
onOpenChange={setShowConfigOptions}
popupRender={() => (
@ -730,7 +730,6 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
placement={"left" as any}
trigger={["click"]}
>
{/* 配置项显示控制按钮 - 齿轮图标 */}
<Tooltip title="config" placement="top">
<button
data-alt="config-toggle-button"
@ -739,7 +738,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
<Settings className="w-4 h-4 text-white/80" />
</button>
</Tooltip>
</Dropdown>
</Dropdown> */}
</div>
)}
@ -771,7 +770,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
<div className="flex items-center justify-between">
{/* 左侧功能按钮区域 */}
<div className="flex items-center gap-2">
{/* 获取创意按钮 */}
{/*
<Tooltip
title="Get creative ideas for your story"
placement="top"
@ -787,10 +786,10 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
<Lightbulb className="w-4 h-4" />
)}
</button>
</Tooltip>
</Tooltip> */}
{/* 分隔线 */}
<div className="w-px h-4 bg-white/[0.20]"></div>
{/* <div className="w-px h-4 bg-white/[0.20]"></div> */}
{/* 模板故事按钮 */}
<Tooltip title="Choose from movie templates" placement="top">
@ -830,6 +829,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
isCreating={isCreating}
handleCreateVideo={handleCreateVideo}
icon={<Clapperboard className="w-5 h-5" />}
className="mr-1 mb-1"
/>
</div>
</div>

View File

@ -12,14 +12,17 @@ import {
LogOut,
PanelsLeftBottom,
Bell,
} from 'lucide-react';
import { motion } from 'framer-motion';
import ReactDOM from 'react-dom';
import { useRouter, usePathname } from 'next/navigation';
import React, { useRef, useEffect, useLayoutEffect, useState } from 'react';
import { logoutUser } from '@/lib/auth';
import { createPortalSession, redirectToPortal, getUserSubscriptionInfo } from '@/lib/stripe';
} from "lucide-react";
import { motion } from "framer-motion";
import ReactDOM from "react-dom";
import { useRouter, usePathname } from "next/navigation";
import React, { useRef, useEffect, useLayoutEffect, useState } from "react";
import { logoutUser } from "@/lib/auth";
import {
createPortalSession,
redirectToPortal,
getUserSubscriptionInfo,
} from "@/lib/stripe";
interface User {
id: string;
@ -27,6 +30,7 @@ interface User {
email: string;
avatar: string;
username: string;
plan_name?: string;
}
export function TopBar({
@ -40,14 +44,14 @@ export function TopBar({
const [isOpen, setIsOpen] = React.useState(false);
const menuRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
const currentUser: User = JSON.parse(
localStorage.getItem("currentUser") || "{}"
const [currentUser, setCurrentUser] = useState<User>(
JSON.parse(localStorage.getItem("currentUser") || "{}")
);
const pathname = usePathname()
const pathname = usePathname();
const [mounted, setMounted] = React.useState(false);
const [isLogin, setIsLogin] = useState(false);
const [isManagingSubscription, setIsManagingSubscription] = useState(false);
const [subscriptionStatus, setSubscriptionStatus] = useState<string>('');
const [subscriptionStatus, setSubscriptionStatus] = useState<string>("");
const [credits, setCredits] = useState<number>(100);
const [isLoadingSubscription, setIsLoadingSubscription] = useState(false);
@ -59,11 +63,18 @@ export function TopBar({
try {
const response = await getUserSubscriptionInfo(String(currentUser.id));
if (response.successful && response.data) {
setSubscriptionStatus(response.data.subscription_status);
const status = response.data.subscription_status;
setSubscriptionStatus(status);
setCredits(response.data.credits);
// 更新 currentUser 的 plan_name
setCurrentUser((prev) => ({
...prev,
plan_name: response.data.plan_name,
}));
}
} catch (error) {
console.error('获取订阅信息失败:', error);
console.error("获取订阅信息失败:", error);
} finally {
setIsLoadingSubscription(false);
}
@ -86,7 +97,7 @@ export function TopBar({
// 处理订阅管理
const handleManageSubscription = async () => {
if (!currentUser?.id) {
console.error('用户未登录');
console.error("用户未登录");
return;
}
@ -94,7 +105,7 @@ export function TopBar({
try {
const response = await createPortalSession({
user_id: String(currentUser.id),
return_url: window.location.origin + '/dashboard'
return_url: window.location.origin + "/dashboard",
});
if (response.successful && response.data?.portal_url) {
@ -199,20 +210,31 @@ export function TopBar({
</div>
</div>
{
isLogin ?(<div className="flex items-center space-x-4">
{isLogin ? (
<div className="flex items-center space-x-4">
{/* Pricing Link */}
<Button
variant="ghost"
size="sm"
onClick={() => {
localStorage.setItem("callBackUrl", pathname);
window.open("/pricing", "_blank");
}}
className="text-gray-300 hover:text-white"
>
Pricing
</Button>
{pathname === "/" ? (
<Button
variant="ghost"
size="sm"
onClick={() => router.push("/create")}
className="bg-white text-black rounded-full hover:bg-gray-100"
>
Go Start
</Button>
) : (
<Button
variant="ghost"
size="sm"
onClick={() => {
localStorage.setItem("callBackUrl", pathname);
window.open("/pricing", "_blank");
}}
className="text-gray-300 hover:text-white"
>
Pricing
</Button>
)}
{/* Notifications */}
{/* <Button variant="ghost" size="sm" onClick={() => showQueueNotification(3, 10)}>
@ -274,9 +296,27 @@ export function TopBar({
MF
</div>
<div className="flex-1">
<p className="text-sm font-medium">
{currentUser.name || currentUser.username}
</p>
<div className="flex items-center gap-2">
<p className="text-sm font-medium">
{currentUser.name || currentUser.username}
</p>
{currentUser.plan_name &&
currentUser.plan_name !== "none" && (
<span
className={`inline-flex items-center px-2 py-1 text-xs font-medium rounded-full ${
currentUser.plan_name === "Kickoff"
? "bg-blue-100 text-blue-800"
: currentUser.plan_name === "Pro"
? "bg-purple-100 text-purple-800"
: currentUser.plan_name === "Ultra"
? "bg-orange-100 text-orange-800"
: ""
}`}
>
{currentUser.plan_name}
</span>
)}
</div>
<p className="text-xs text-gray-500">
{currentUser.email}
</p>
@ -298,7 +338,9 @@ export function TopBar({
<div className="flex items-center space-x-2">
<Sparkles className="h-4 w-4" />
<span className="text-white underline text-sm">
{isLoadingSubscription ? '...' : `${credits} credits`}
{isLoadingSubscription
? "..."
: `${credits} credits`}
</span>
</div>
<Button
@ -311,7 +353,7 @@ export function TopBar({
>
Upgrade
</Button>
{subscriptionStatus === 'ACTIVE' && (
{subscriptionStatus === "ACTIVE" && (
<Button
variant="outline"
size="sm"
@ -323,62 +365,34 @@ export function TopBar({
</Button>
)}
</div>
{/* Menu Items */}
<div className="p-2">
{/* <motion.button
whileHover={{ backgroundColor: 'rgba(255,255,255,0.1)' }}
className="w-full flex items-center space-x-2 px-3 py-2 rounded-md text-sm text-white"
onClick={() => router.push('/my-library')}
data-alt="my-library-button"
>
<Library className="h-4 w-4" />
<span>My Library</span>
</motion.button>
<motion.button
whileHover={{ backgroundColor: 'rgba(255,255,255,0.1)' }}
className="w-full flex items-center space-x-2 px-3 py-2 rounded-md text-sm text-white"
onClick={() => {
// 处理退出登录
setIsOpen(false);
}}
data-alt="logout-button"
>
<LogOut className="h-4 w-4" />
<span>Logout</span>
</motion.button> */}
{/* Footer */}
<div className="mt-4 px-3 py-2 text-xs text-gray-400 text-center">
<div>Privacy Policy · Terms of Service</div>
<div>250819215404 | 2025/8/20 06:00:50</div>
</div>
</div>
</motion.div>,
document.body
)
: null}
</div>
</div>):(
<div className="flex items-center space-x-4">
<button
data-alt="login-button"
className="w-[8.5rem] h-[3rem] text-base text-gray-300 hover:text-white transition-colors"
onClick={() => router.push("/login")}
>
Login
</button>
<button
data-alt="signup-button"
className="w-[8.5rem] h-[3rem] text-base bg-gray-200 text-gray-800 rounded-full hover:bg-white transition-colors"
onClick={() => router.push("/signup")}
>
Sign Up
</button>
</div>
)
}
</div>
) : (
<div className="flex items-center space-x-4">
<Button
variant="ghost"
size="sm"
onClick={() => router.push("/login")}
className="text-gray-300 hover:text-white"
data-alt="login-button"
>
Login
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => router.push("/signup")}
className="bg-gray-200 text-gray-800 rounded-full hover:bg-white"
data-alt="signup-button"
>
Sign Up
</Button>
</div>
)}
</div>
</div>
);

View File

@ -622,7 +622,7 @@ function HomeModule5() {
>
<div
data-alt="core-value-content"
className="center z-10 flex flex-col items-center mb-[8rem]"
className="center z-10 flex flex-col items-center mb-[4rem]"
>
<h2 className="text-white text-[3.375rem] leading-[100%] font-normal mb-[1.5rem]">
Pick a plan and make it yours