Skip to content

Commit 363e591

Browse files
authored
Merge pull request #695 from ItsFlash10/feat-canva
feat: add canva embed and route
2 parents 48ada6a + 5a6c456 commit 363e591

File tree

7 files changed

+173
-15
lines changed

7 files changed

+173
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"use client";
2+
3+
import React from "react";
4+
import { useSearchParams } from "next/navigation";
5+
import { motion } from "framer-motion";
6+
import Link from "next/link";
7+
import Image from "next/image";
8+
9+
const Header = ({ title }: { title: string }) => (
10+
<motion.div
11+
className={`z-[50] flex w-full flex-col justify-between gap-2 p-6 md:flex-row`}
12+
initial={{ y: 0 }}
13+
animate={{ y: 0 }}
14+
transition={{ duration: 0.3 }}
15+
>
16+
<div className="flex items-center gap-2">
17+
<motion.div
18+
initial={{ y: -20, opacity: 0 }}
19+
animate={{ y: 0, opacity: 1 }}
20+
transition={{ duration: 0.5, ease: "easeInOut", type: "spring", damping: 10 }}
21+
className="flex justify-between gap-2"
22+
>
23+
<div
24+
className={`border-primary/10 flex items-center gap-4 rounded-lg border bg-black/10 p-2 backdrop-blur-lg transition-all duration-500 ease-in-out`}
25+
>
26+
<Link href={"/"} className="cursor-pointer items-center gap-4">
27+
<Image
28+
src={"https://appx-wsb-gcp.akamai.net.in/subject/2023-01-17-0.17044360120951185.jpg"}
29+
alt="Logo"
30+
width={200}
31+
height={200}
32+
className="size-8 rounded-full"
33+
/>
34+
</Link>
35+
<h4 className="flex items-center gap-2 font-medium tracking-tighter md:max-w-[50vw] md:text-lg">{title}</h4>
36+
</div>
37+
</motion.div>
38+
</div>
39+
</motion.div>
40+
);
41+
42+
export default function CanvaTrack() {
43+
const searchParams = useSearchParams();
44+
const canvaLink = searchParams.get("canvaLink");
45+
const title = searchParams.get("title");
46+
47+
const embedUrl = canvaLink?.includes("?embed") ? canvaLink : `${canvaLink}?embed`;
48+
49+
console.log({ canvaLink, embedUrl });
50+
51+
if (!embedUrl) {
52+
return <div>No Canva presentation link provided</div>;
53+
}
54+
55+
return (
56+
<div className="flex h-screen w-full flex-col overflow-hidden">
57+
<Header title={title ?? ""} />
58+
<div className="w-full flex-1">
59+
<div className="relative h-full w-full">
60+
<iframe
61+
loading="lazy"
62+
className="absolute left-0 top-0 h-full w-full border-none"
63+
src={embedUrl}
64+
allowFullScreen={true}
65+
allow="fullscreen"
66+
/>
67+
</div>
68+
</div>
69+
</div>
70+
);
71+
}

apps/web/components/TrackCard-2.tsx

+17-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { motion, useAnimation } from "framer-motion";
33
import { Track, Problem } from "@prisma/client";
44
import { TrackPreview } from "./TrackPreview";
55
import { formatDistanceToNow } from "date-fns";
6+
import { useRouter } from "next/navigation";
67

78
interface TrackCardProps extends Track {
89
problems: Problem[];
@@ -15,10 +16,24 @@ interface TrackCardProps extends Track {
1516
}
1617

1718
export function TrackCard2({ track }: { track: TrackCardProps }) {
19+
const router = useRouter();
1820
const controls = useAnimation();
1921
const ref = useRef<HTMLDivElement | null>(null);
2022
const [showPreview, setShowPreview] = useState<boolean>(false);
2123

24+
const handleTrackClick = () => {
25+
if (track.trackType === "CANVA") {
26+
const searchParams = new URLSearchParams();
27+
if (track.canvaLink) {
28+
searchParams.set("canvaLink", track.canvaLink);
29+
searchParams.set("title", track.title);
30+
}
31+
router.push(`/canva-track/${track.id}?${searchParams.toString()}`);
32+
} else {
33+
setShowPreview(true);
34+
}
35+
};
36+
2237
useEffect(() => {
2338
const observer = new IntersectionObserver(
2439
([entry]) => {
@@ -52,8 +67,8 @@ export function TrackCard2({ track }: { track: TrackCardProps }) {
5267
initial="hidden"
5368
animate={controls}
5469
variants={variants}
55-
className="flex items-start flex-row gap-4 cursor-pointer transition-all bg-primary/5 backdrop-blur-xl duration-300 hover:-translate-y-1 rounded-xl p-4 justify-between md:items-center"
56-
onClick={() => setShowPreview(true)}
70+
className="bg-primary/5 flex cursor-pointer flex-row items-start justify-between gap-4 rounded-xl p-4 backdrop-blur-xl transition-all duration-300 hover:-translate-y-1 md:items-center"
71+
onClick={handleTrackClick}
5772
>
5873
<img src={track.image} alt={track.title} className="size-20 aspect-square object-cover rounded-xl" />
5974
<div className="flex flex-col md:flex-row gap-4 w-full md:items-center justify-between">

apps/web/components/admin/AddTrackCard.tsx

+36-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => {
1414
const [hidden, setHidden] = useState(false);
1515
const [selectedCategory, setSelectedCategory] = useState<string[]>([]);
1616
const [cohort, setCohort] = useState(3);
17+
const [canvaLink, setCanvaLink] = useState("");
1718
const { toast } = useToast();
1819

1920
function handleFilterButton(category: string) {
@@ -26,7 +27,7 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => {
2627

2728
return (
2829
<div>
29-
<Card className="cols-span-4 p-4 m-2 w-full">
30+
<Card className="cols-span-4 m-2 w-full p-4">
3031
<Input
3132
type="text"
3233
placeholder="Track Id"
@@ -68,7 +69,16 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => {
6869
setCohort(parseInt(event.target.value));
6970
}}
7071
/>
71-
<div className="flex lg:flex-row justify-evenly mx-auto py-1">
72+
<Input
73+
type="text"
74+
placeholder="Canva Link"
75+
className="my-2"
76+
value={canvaLink}
77+
onChange={(event) => {
78+
setCanvaLink(event.target.value);
79+
}}
80+
/>
81+
<div className="mx-auto flex justify-evenly py-1 lg:flex-row">
7282
{categories.map((category, i) => (
7383
<Button
7484
key={i}
@@ -85,12 +95,32 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => {
8595
</Button>
8696
<Button
8797
disabled={!title || !description || !image}
88-
className="w-full mt-4"
98+
className="mt-4 w-full"
8999
onClick={async () => {
90-
await createTrack({ problems: [], id, title, description, image, hidden, selectedCategory });
100+
await createTrack({
101+
problems: [],
102+
id,
103+
title,
104+
description,
105+
image,
106+
hidden,
107+
selectedCategory,
108+
canvaLink,
109+
trackType: canvaLink ? "CANVA" : "NOTION",
110+
});
91111
setNewProblems((prev) => [
92112
...prev,
93-
{ id, title, description, image, hidden, cohort, createdAt: new Date() },
113+
{
114+
id,
115+
title,
116+
description,
117+
image,
118+
hidden,
119+
cohort,
120+
createdAt: new Date(),
121+
canvaLink,
122+
trackType: canvaLink ? "CANVA" : "NOTION",
123+
},
94124
]);
95125
toast({
96126
title: "Added a Track",
@@ -107,7 +137,7 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => {
107137
<div className="grid grid-cols-6">
108138
<img
109139
src={Track.image}
110-
className="flex m-4 min-h-[130px] sm:h-[130px] min-w-[130px] sm:w-[130px] rounded-xl"
140+
className="m-4 flex min-h-[130px] min-w-[130px] rounded-xl sm:h-[130px] sm:w-[130px]"
111141
/>
112142
<div className="col-span-5">
113143
<CardHeader>

apps/web/components/admin/EditTrackCard.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
2020
const [image, setImage] = useState(Track.image);
2121
const [hidden, setHidden] = useState(Track.hidden);
2222
const [cohort, setCohort] = useState(Track.cohort);
23+
const [trackType, setTrackType] = useState(Track.trackType);
24+
const [canvaLink, setCanvaLink] = useState(Track.canvaLink || "");
25+
2326
const [selectedCategory, setSelectedCategory] = useState<string[]>(Track.categories.map((item) => item.category.id));
2427

2528
function handleEdit(id: string) {
2629
if (isEditing) {
27-
updateTrack(id, { id, title, description, image, hidden, selectedCategory, cohort });
30+
updateTrack(id, { id, title, description, image, hidden, selectedCategory, cohort, trackType, canvaLink });
2831
return setIsEditing(false);
2932
}
3033
setIsEditing(true);
@@ -50,7 +53,7 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
5053
<Card key={Track.id}>
5154
{!isEditing && (
5255
<div className="grid grid-cols-6">
53-
<img src={image} className="flex m-4 min-h-[130px] sm:h-[130px] min-w-[130px] sm:w-[130px] rounded-xl" />
56+
<img src={image} className="m-4 flex min-h-[130px] min-w-[130px] rounded-xl sm:h-[130px] sm:w-[130px]" />
5457
<div className="col-span-5">
5558
<CardHeader>
5659
<div className="flex justify-between">
@@ -96,6 +99,24 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
9699
<Label>Cohort</Label>
97100
<Input placeholder="Cohort" onChange={(e) => setCohort(Number(e.target.value))} value={cohort} />
98101
</CardDescription>
102+
{trackType === "CANVA" && canvaLink && (
103+
<CardDescription>
104+
<Label>Canva Link</Label>
105+
<Input
106+
placeholder="Canva Link"
107+
onChange={(e) => {
108+
if (e.target.value === "") {
109+
setCanvaLink("");
110+
setTrackType("NOTION");
111+
} else {
112+
setTrackType("CANVA");
113+
setCanvaLink(e.target.value);
114+
}
115+
}}
116+
value={canvaLink}
117+
/>
118+
</CardDescription>
119+
)}
99120
<CardDescription>
100121
{categories.map((item, i) => (
101122
<Button

apps/web/components/utils.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ export async function createTrack(data: {
212212
problems: { problem: Prisma.ProblemCreateManyInput; sortingOrder: number }[];
213213
hidden: boolean;
214214
cohort?: number;
215+
canvaLink?: string;
216+
trackType: "NOTION" | "CANVA";
215217
}) {
216218
try {
217219
await db.problem.createMany({
@@ -225,6 +227,8 @@ export async function createTrack(data: {
225227
description: data.description,
226228
image: data.image,
227229
cohort: data.cohort,
230+
canvaLink: data.canvaLink,
231+
trackType: data.trackType,
228232
hidden: data.hidden,
229233
problems: {
230234
createMany: {
@@ -264,6 +268,8 @@ export async function updateTrack(
264268
problems?: { problem: Prisma.ProblemCreateManyInput; sortingOrder: number }[];
265269
hidden: boolean;
266270
cohort?: number;
271+
canvaLink?: string;
272+
trackType: "NOTION" | "CANVA";
267273
}
268274
) {
269275
try {
@@ -278,6 +284,8 @@ export async function updateTrack(
278284
image: data.image,
279285
hidden: data.hidden,
280286
cohort: data.cohort,
287+
canvaLink: data.canvaLink,
288+
trackType: data.trackType,
281289
},
282290
});
283291
await db.trackCategory.deleteMany({
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- CreateEnum
2+
CREATE TYPE "TrackType" AS ENUM ('NOTION', 'CANVA');
3+
4+
-- AlterTable
5+
ALTER TABLE "Track" ADD COLUMN "canvaLink" TEXT,
6+
ADD COLUMN "trackType" "TrackType" NOT NULL DEFAULT 'NOTION';

packages/db/prisma/schema.prisma

+12-5
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ model Track {
6868
image String
6969
categories TrackCategory[] // This replaces 'category Categories[]'
7070
problems TrackProblems[]
71-
inSearch Boolean @default(false)
72-
hidden Boolean @default(false)
73-
cohort Int @default(0)
74-
createdAt DateTime @default(now())
71+
canvaLink String?
72+
trackType TrackType @default(NOTION)
73+
inSearch Boolean @default(false)
74+
hidden Boolean @default(false)
75+
cohort Int @default(0)
76+
createdAt DateTime @default(now())
7577
}
7678

7779
model Categories {
@@ -133,4 +135,9 @@ model QuizScore {
133135
problem Problem @relation(fields: [problemId], references: [id])
134136
problemId String
135137
createdAt DateTime @default(now())
136-
}
138+
}
139+
140+
enum TrackType {
141+
NOTION
142+
CANVA
143+
}

0 commit comments

Comments
 (0)