Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDF Wiring #75

Merged
merged 9 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions src/components/DeleteComponentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import {
import chakraTheme from "@/styles/chakraTheme";
import { useRouter } from "next/router";
import { useRef, Dispatch } from "react";
import { populatedGameWithId } from "@/server/db/models/GameModel";
import { GameDataState } from "./GameScreen/GamePage";

interface Props {
deleteType: string;
isOpen: boolean;
onClose: () => void;
gameData: populatedGameWithId;
setGameData: Dispatch<populatedGameWithId>;
gameData: GameDataState;
setGameData: Dispatch<React.SetStateAction<GameDataState | undefined>>;
}

export default function DeleteComponentModal(props: Props) {
Expand Down Expand Up @@ -72,11 +72,31 @@ export default function DeleteComponentModal(props: Props) {
router.push("/games");
}

async function deleteAnswerKey() {}
async function deleteAnswerKey() {
if (!props.gameData) return;
props.setGameData({
...props.gameData,
answerKey: "",
answerKeyFile: undefined,
});
props.onClose();
}

async function deleteParentingGuide() {}
async function deleteParentingGuide() {
if (!props.gameData) return;
props.setGameData({
...props.gameData,
parentingGuide: "",
parentingGuideFile: undefined,
});
props.onClose();
}

async function deleteLessonPlan() {}
async function deleteLessonPlan() {
if (!props.gameData) return;
props.setGameData({ ...props.gameData, lesson: "", lessonFile: undefined });
props.onClose();
}

async function deleteTrailer() {
if (props.gameData) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/GameScreen/AddEditVideoTrailerComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import {
import chakraTheme from "@/styles/chakraTheme";
import { useRouter } from "next/router";
import { useRef, useState, useEffect, Dispatch } from "react";
import { populatedGameWithId } from "@/server/db/models/GameModel";
import { GameDataState } from "./GamePage";
export const youtubeREGEX =
/^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(-nocookie)?\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|live\/|v\/)?)([\w\-]+)(\S+)?$/;
export const vimeoREGEX =
/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
interface Props {
gameData: populatedGameWithId;
setGameData: Dispatch<populatedGameWithId>;
gameData: GameDataState;
setGameData: Dispatch<GameDataState>;
}

export default function AddEditVideoTrailer({ gameData, setGameData }: Props) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/GameScreen/GameBuildList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Image from "next/image";
import { NonWebGLBuilds, buildSchema } from "@/utils/types";
import { AlertTriangleIcon, Download, Pencil, Plus, Trash } from "lucide-react";
import { z } from "zod";
import { populatedGameWithId } from "@/server/db/models/GameModel";
import { Label } from "@/components/ui/label";
import {
Select,
Expand All @@ -22,11 +21,12 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { GameDataState } from "../GameScreen/GamePage";

interface Props {
gameData: populatedGameWithId;
gameData: GameDataState;
editing: boolean;
setGameData?: React.Dispatch<populatedGameWithId>;
setGameData?: React.Dispatch<GameDataState>;
}

function GameBuildList({ gameData, editing, setGameData }: Props) {
Expand Down
16 changes: 14 additions & 2 deletions src/components/GameScreen/GamePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@ import {
import chakraTheme from "@/styles/chakraTheme";
import { Button } from "@/components/ui/button";

export type GameDataState = populatedGameWithId & {
parentingGuideFile: File | undefined;
answerKeyFile: File | undefined;
lessonFile: File | undefined;
};

interface Props {
mode: "view" | "preview";
}

const GamePage = ({ mode }: Props) => {
const gameId = useRouter().query.id as string;
const [gameData, setGameData] = useState<populatedGameWithId>();
const [gameData, setGameData] = useState<GameDataState | undefined>();
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
const router = useRouter();
Expand Down Expand Up @@ -219,6 +225,7 @@ const GamePage = ({ mode }: Props) => {
<TabsComponent
mode="view"
gameData={gameData}
setGameData={setGameData}
authorized={visibleAnswer}
/>
{loaded && userData.label !== "administrator" && (
Expand All @@ -227,7 +234,12 @@ const GamePage = ({ mode }: Props) => {
{loaded && userData.label !== "administrator" && (
<ContactComponent gameName={gameData.name} />
)}
<TagsComponent mode="view" gameData={gameData} admin={visibleAnswer} />
<TagsComponent
mode="view"
gameData={gameData}
setGameData={setGameData}
admin={visibleAnswer}
/>
{loaded && mode === "preview" && (
<div className="relative my-10 flex w-11/12 justify-end gap-6 font-sans">
<ChakraProvider theme={chakraTheme}>
Expand Down
171 changes: 164 additions & 7 deletions src/components/Tabs/TabsComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ import {
Tab,
TabPanel,
ChakraProvider,
useDisclosure,
} from "@chakra-ui/react";
import chakraTheme from "@/styles/chakraTheme";
import { populatedGameWithId } from "@/server/db/models/GameModel";
import { ChangeEvent, Dispatch, useState } from "react";
import GameBuildList from "../GameScreen/GameBuildList";
import VideoComponent from "./VideoComponent";
import { Button } from "../ui/button";
import { X } from "lucide-react";
import UploadModal from "./UploadModal";
import DeleteComponentModal from "../DeleteComponentModal";
import { GameDataState } from "../GameScreen/GamePage";

interface Props {
mode: string;
gameData: populatedGameWithId;
setGameData?: Dispatch<populatedGameWithId>;
gameData: GameDataState;
setGameData: Dispatch<React.SetStateAction<GameDataState | undefined>>;
authorized?: boolean;
}

Expand All @@ -24,6 +30,21 @@ export default function TabsComponent({
setGameData,
authorized,
}: Props) {
const {
isOpen: isDeleteLessonOpen,
onOpen: onDeleteLessonOpen,
onClose: onDeleteLessonClose,
} = useDisclosure();
const {
isOpen: isDeleteParentingGuideOpen,
onOpen: onDeleteParentingGuideOpen,
onClose: onDeleteParentingGuideClose,
} = useDisclosure();
const {
isOpen: isDeleteAnswerKeyOpen,
onOpen: onDeleteAnswerKeyOpen,
onClose: onDeleteAnswerKeyClose,
} = useDisclosure();
const [description, setDescription] = useState(gameData.description);
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const newValue = e.target.value;
Expand Down Expand Up @@ -73,7 +94,7 @@ export default function TabsComponent({
</>
)}
</TabList>
<TabPanels className="mb-12 mt-8 text-gray-500">
<TabPanels className="mb-12 mt-8 text-gray-500">
{/** description tab display depends on edit or view mode */}
<TabPanel p="0px">
{mode === "edit" ? (
Expand All @@ -100,11 +121,147 @@ export default function TabsComponent({
</TabPanel>
)}
{((gameData.lesson && gameData.lesson !== "") ||
mode === "edit") && <TabPanel>Lesson Plan</TabPanel>}
mode === "edit") && (
<TabPanel display="flex" flexDir="column" gap={2}>
{((gameData.lesson && gameData.lesson !== "") ||
gameData.lessonFile) && (
<iframe
className="w-full"
height="400"
src={
gameData.lessonFile
? URL.createObjectURL(gameData.lessonFile as File)
: gameData.lesson
}
/>
)}
{mode === "edit" && (
<div className="flex flex-row gap-2">
<UploadModal
title="Lesson Plan"
field="lesson"
fileField="lessonFile"
gameData={gameData}
setGameData={setGameData}
/>
{((gameData.lesson && gameData.lesson !== "") ||
gameData.lessonFile) && (
<Button
type="button"
variant="outline"
className="items-center gap-1 border-red-700 text-red-700 hover:bg-red-700"
onClick={onDeleteLessonOpen}
>
Delete Lesson Plan <X size={18} />
</Button>
)}
<DeleteComponentModal
isOpen={isDeleteLessonOpen}
onClose={onDeleteLessonClose}
gameData={gameData}
setGameData={setGameData}
deleteType="lessonPlan"
/>
</div>
)}
</TabPanel>
)}
{((gameData.parentingGuide && gameData.parentingGuide !== "") ||
mode === "edit") && <TabPanel>Parenting Guide</TabPanel>}
mode === "edit") && (
<TabPanel display="flex" flexDir="column" gap={2}>
{((gameData.parentingGuide && gameData.parentingGuide !== "") ||
gameData.parentingGuideFile) && (
<iframe
className="w-full"
height="400"
src={
gameData.parentingGuideFile
? URL.createObjectURL(
gameData.parentingGuideFile as File,
)
: gameData.parentingGuide
}
/>
)}

{mode === "edit" && (
<div className="flex flex-row gap-2">
<UploadModal
title="Parenting Guide"
field="parentingGuide"
fileField="parentingGuideFile"
gameData={gameData}
setGameData={setGameData}
/>
{((gameData.parentingGuide &&
gameData.parentingGuide !== "") ||
gameData.parentingGuideFile) && (
<Button
type="button"
variant="outline"
className="items-center gap-1 border-red-700 text-red-700 hover:bg-red-700"
onClick={onDeleteParentingGuideOpen}
>
Delete Parenting Guide <X size={18} />
</Button>
)}
<DeleteComponentModal
isOpen={isDeleteParentingGuideOpen}
onClose={onDeleteParentingGuideClose}
gameData={gameData}
setGameData={setGameData}
deleteType="parentingGuide"
/>
</div>
)}
</TabPanel>
)}
{((gameData.answerKey && gameData.answerKey !== "" && authorized) ||
mode === "edit") && <TabPanel>Answer Key</TabPanel>}
mode === "edit") && (
<TabPanel display="flex" flexDir="column" gap={2}>
{((gameData.answerKey && gameData.answerKey !== "") ||
gameData.answerKeyFile) && (
<iframe
className="w-full"
height="400"
src={
gameData.answerKeyFile
? URL.createObjectURL(gameData.answerKeyFile as File)
: gameData.answerKey
}
/>
)}
{mode === "edit" && (
<div className="flex flex-row gap-2">
<UploadModal
title="Answer Key"
field="answerKey"
fileField="answerKeyFile"
gameData={gameData}
setGameData={setGameData}
/>
{((gameData.answerKey && gameData.answerKey !== "") ||
gameData.answerKeyFile) && (
<Button
type="button"
variant="outline"
className="items-center gap-1 border-red-700 text-red-700 hover:bg-red-700"
onClick={onDeleteAnswerKeyOpen}
>
Delete Answer Key <X size={18} />
</Button>
)}
<DeleteComponentModal
isOpen={isDeleteAnswerKeyOpen}
onClose={onDeleteAnswerKeyClose}
gameData={gameData}
setGameData={setGameData}
deleteType="answerKey"
/>
</div>
)}
</TabPanel>
)}
{((gameData?.builds && gameData.builds.length > 0) ||
mode === "edit") && (
<TabPanel>
Expand Down
Loading
Loading