This commit is contained in:
eric
2026-03-12 03:54:22 -05:00
parent 421f979e10
commit e7dde61e31
23 changed files with 876 additions and 125 deletions

View File

@@ -7,6 +7,7 @@ import { VideoPlayer } from "@/app/components/course/VideoPlayer";
import { LessonMarkdown } from "./LessonMarkdown";
import { getLesson } from "@/config/lessons";
import { canWatchLesson } from "@/app/lib/course-payment";
import { useAuthAndVip } from "@/app/lib/useAuthAndVip";
import { setLastWatched, markCompleted } from "@/app/lib/learning";
import { DOWNLOAD_CONFIG } from "@/config/course";
import Header from "@/app/components/Header";
@@ -15,12 +16,13 @@ export default function LessonPage() {
const params = useParams();
const router = useRouter();
const { t } = useTranslation("community");
const { vip } = useAuthAndVip();
const [toast, setToast] = useState(false);
const moduleIndex = Number(params.moduleIndex);
const lessonIndex = Number(params.lessonIndex);
const lesson = getLesson(moduleIndex, lessonIndex);
const unlocked = canWatchLesson(moduleIndex, lessonIndex);
const unlocked = canWatchLesson(moduleIndex, lessonIndex, vip);
const isFreeTrial = moduleIndex === 0 && lessonIndex < 2;
useEffect(() => {

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useRef, useEffect, type FormEvent, type ChangeEvent } from "react";
import { useState, useRef, useEffect, useCallback, type FormEvent, type ChangeEvent } from "react";
import { Link } from "@/i18n/navigation";
import {
getPayEnv,
@@ -11,6 +11,8 @@ import {
} from "@/app/lib/payment";
import { usePayStatusPoll } from "@/app/lib/payment/usePayStatusPoll";
import type { PayChannel, PayEnv } from "@/app/lib/payment";
import { getStoredToken } from "@/app/lib/pocketbase";
import AuthModal from "@/app/components/AuthModal";
const genderOptions = ["男", "女"];
const singleOptions = ["单身", "恋爱中", "已婚"];
@@ -56,6 +58,18 @@ export default function JoinPage() {
const [payRedirecting, setPayRedirecting] = useState(false);
const [payEnv, setPayEnv] = useState<PayEnv | null>(null);
const [payChannel, setPayChannel] = useState<PayChannel>("alipay");
const [authOpen, setAuthOpen] = useState(false);
const checkAuth = useCallback(async () => {
if (getStoredToken()) return true;
try {
const res = await fetch("/api/auth/me");
const data = await res.json();
return !!(data?.user && data?.token);
} catch {
return false;
}
}, []);
useEffect(() => {
if (typeof window !== "undefined" && new URLSearchParams(window.location.search).get("paid") === "1") {
@@ -79,6 +93,12 @@ export default function JoinPage() {
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
setError(null);
const loggedIn = await checkAuth();
if (!loggedIn) {
setAuthOpen(true);
setError("请先登录或注册后再提交申请");
return;
}
setSubmitting(true);
try {
const res = await fetch("/api/join", {
@@ -515,6 +535,15 @@ export default function JoinPage() {
</Link>
</div>
</div>
<AuthModal
isOpen={authOpen}
onClose={() => setAuthOpen(false)}
onSuccess={() => {
setAuthOpen(false);
setError(null);
}}
/>
</div>
);
}