video new
This commit is contained in:
parent
c31325e01a
commit
d9a8d171fb
985
package-lock.json
generated
985
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@
|
||||
"hls.js": "^1.6.13",
|
||||
"idb": "^8.0.3",
|
||||
"media-chrome": "^4.15.0",
|
||||
"next": "15.3.3",
|
||||
"next": "^15.5.6",
|
||||
"next-intl": "^4.1.0",
|
||||
"react": "^19.0.0",
|
||||
"react-circular-progressbar": "^2.2.0",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { VideoGuideView } from "@/components/domains/video-guides";
|
||||
import { DashboardData, DashboardSchema } from "@/entities/dashboard/types";
|
||||
import { VideoGuideSchema } from "@/entities/dashboard/types";
|
||||
import { http } from "@/shared/api/httpClient";
|
||||
import { API_ROUTES } from "@/shared/constants/api-routes";
|
||||
|
||||
@ -15,15 +15,17 @@ export default async function VideoGuidePage({
|
||||
}) {
|
||||
const { id } = await params;
|
||||
|
||||
// Get fresh dashboard data without cache
|
||||
const dashboard = await http.get<DashboardData>(API_ROUTES.dashboard(), {
|
||||
cache: "no-store",
|
||||
schema: DashboardSchema,
|
||||
});
|
||||
// Get specific video guide data from new API
|
||||
const response = await http.get<{ status: string; data: typeof VideoGuideSchema._type }>(
|
||||
API_ROUTES.videoGuide(id),
|
||||
{
|
||||
cache: "no-store",
|
||||
}
|
||||
);
|
||||
|
||||
const videoGuide = dashboard.videoGuides?.find(v => v.id === id);
|
||||
const videoGuide = response.data;
|
||||
|
||||
if (!videoGuide || !videoGuide.isPurchased || !videoGuide.videoLink) {
|
||||
if (!videoGuide || !videoGuide.isPurchased) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
@ -32,7 +34,8 @@ export default async function VideoGuidePage({
|
||||
id={videoGuide.id}
|
||||
name={videoGuide.name}
|
||||
description={videoGuide.description}
|
||||
videoLink={videoGuide.videoLink}
|
||||
videoLinkHLS={videoGuide.videoLinkHLS}
|
||||
videoLinkDASH={videoGuide.videoLinkDASH}
|
||||
contentUrl={videoGuide.contentUrl}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -71,6 +71,7 @@ export default function VideoGuideCard(props: VideoGuideCardProps) {
|
||||
alt={name}
|
||||
width={260}
|
||||
height={160}
|
||||
priority
|
||||
unoptimized
|
||||
className={styles.imageContent}
|
||||
/>
|
||||
|
||||
@ -18,17 +18,16 @@ function VideoGuideCardWrapper({ videoGuide }: { videoGuide: VideoGuide }) {
|
||||
const { handlePurchase, isCheckoutLoading, isProcessingPurchase } =
|
||||
useVideoGuidePurchase({
|
||||
videoGuideId: videoGuide.id,
|
||||
productId: videoGuide.id,
|
||||
productId: videoGuide.productId, // Используем productId из payment-service
|
||||
productKey: videoGuide.key,
|
||||
});
|
||||
|
||||
// Для купленных видео - ссылка на страницу просмотра
|
||||
const href =
|
||||
videoGuide.isPurchased && videoGuide.videoLink
|
||||
? `/video-guides/${videoGuide.id}`
|
||||
: "#";
|
||||
const href = videoGuide.isPurchased
|
||||
? `/video-guides/${videoGuide.id}`
|
||||
: "#";
|
||||
|
||||
const isClickable = videoGuide.isPurchased && videoGuide.videoLink;
|
||||
const isClickable = videoGuide.isPurchased;
|
||||
|
||||
const cardElement = (
|
||||
<VideoGuideCard
|
||||
|
||||
@ -14,14 +14,16 @@ interface VideoGuideViewProps {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
videoLink: string;
|
||||
videoLinkHLS: string;
|
||||
videoLinkDASH: string;
|
||||
contentUrl?: string;
|
||||
}
|
||||
|
||||
export default function VideoGuideView({
|
||||
name,
|
||||
description,
|
||||
videoLink,
|
||||
videoLinkHLS,
|
||||
videoLinkDASH,
|
||||
contentUrl,
|
||||
}: VideoGuideViewProps) {
|
||||
const router = useRouter();
|
||||
@ -51,13 +53,6 @@ export default function VideoGuideView({
|
||||
loadMarkdown();
|
||||
}, [contentUrl]);
|
||||
|
||||
// TODO: Remove hardcoded URLs when backend is ready
|
||||
// Temporary hardcoded DASH/HLS URLs - using for ALL videos until backend updated
|
||||
const dashUrl = "https://video.witlab.us/videos/TALK_FEELINGS/cmaf/source.mpd";
|
||||
const hlsUrl = "https://video.witlab.us/videos/TALK_FEELINGS/cmaf/source.m3u8";
|
||||
|
||||
const _originalVideoLink = videoLink; // Keep for reference when backend is ready
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{/* Header with back button and title */}
|
||||
@ -79,7 +74,7 @@ export default function VideoGuideView({
|
||||
<div className={styles.contentWrapper}>
|
||||
{/* Video Player */}
|
||||
<div className={styles.videoContainer}>
|
||||
<VideoPlayer mpd={dashUrl} m3u8={hlsUrl} />
|
||||
<VideoPlayer mpd={videoLinkDASH} m3u8={videoLinkHLS} />
|
||||
</div>
|
||||
|
||||
{/* Description or Markdown Content */}
|
||||
|
||||
@ -64,6 +64,7 @@ export type PartnerPortrait = z.infer<typeof PartnerPortraitSchema>;
|
||||
/* ---------- Video Guide ---------- */
|
||||
export const VideoGuideSchema = z.object({
|
||||
id: z.string(),
|
||||
productId: z.string(), // ID продукта для покупки
|
||||
key: z.string(),
|
||||
type: z.string(),
|
||||
name: z.string(),
|
||||
@ -74,7 +75,8 @@ export const VideoGuideSchema = z.object({
|
||||
oldPrice: z.number(),
|
||||
discount: z.number(),
|
||||
isPurchased: z.boolean(),
|
||||
videoLink: z.string().optional(),
|
||||
videoLinkHLS: z.string(), // HLS format (.m3u8)
|
||||
videoLinkDASH: z.string(), // DASH format (.mpd)
|
||||
contentUrl: z.string().optional(), // URL to markdown content file
|
||||
});
|
||||
export type VideoGuide = z.infer<typeof VideoGuideSchema>;
|
||||
|
||||
@ -35,8 +35,8 @@ export function useVideoGuidePurchase(options: UseVideoGuidePurchaseOptions) {
|
||||
// Включаем лоадер на всей карточке
|
||||
setIsProcessingPurchase(true);
|
||||
|
||||
// Ждем 4 секунды
|
||||
await new Promise(resolve => setTimeout(resolve, 4000));
|
||||
// Ждем 3 секунды перед обновлением
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
|
||||
// Обновляем данные dashboard в transition
|
||||
// isPending будет true пока данные загружаются
|
||||
|
||||
@ -13,6 +13,8 @@ const createRoute = (
|
||||
|
||||
export const API_ROUTES = {
|
||||
dashboard: () => createRoute(["dashboard"]),
|
||||
videoGuides: () => createRoute(["video-guides"], ROOT_ROUTE_V2),
|
||||
videoGuide: (id: string) => createRoute(["video-guides", id], ROOT_ROUTE_V2),
|
||||
checkVideoGuidePurchase: (productKey: string) =>
|
||||
createRoute(["products", "video-guides", productKey, "check-purchase"]),
|
||||
subscriptions: () => createRoute(["payment", "subscriptions"], ROOT_ROUTE_V3),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user