feat: improve activity type chooser UI

This commit is contained in:
swve 2023-04-08 20:28:51 +02:00
parent 5eabb0b16a
commit 7202baa122
7 changed files with 149 additions and 50 deletions

View file

@ -256,7 +256,8 @@ function CourseEdit(params: any) {
<Modal <Modal
isDialogOpen={newActivityModal} isDialogOpen={newActivityModal}
onOpenChange={setNewActivityModal} onOpenChange={setNewActivityModal}
minHeight="md" minHeight="no-min"
addDefCloseButton={false}
dialogContent={<NewActivityModal dialogContent={<NewActivityModal
closeModal={closeNewActivityModal} closeModal={closeNewActivityModal}
submitFileActivity={submitFileActivity} submitFileActivity={submitFileActivity}

View file

@ -1,25 +1,38 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { ArrowLeftIcon, Cross1Icon } from "@radix-ui/react-icons"; import { ArrowLeftIcon, Cross1Icon } from "@radix-ui/react-icons";
import styled from "styled-components"; import DynamicPageActivityImage from "public/activities_types/dynamic-page-activity.png";
import VideoPageActivityImage from "public//activities_types/video-page-activity.png";
import { styled, keyframes } from '@stitches/react';
import DynamicCanvaModal from "./NewActivityModal/DynamicCanva"; import DynamicCanvaModal from "./NewActivityModal/DynamicCanva";
import VideoModal from "./NewActivityModal/Video"; import VideoModal from "./NewActivityModal/Video";
import Image from "next/image";
function NewActivityModal({ closeModal, submitActivity, submitFileActivity, chapterId }: any) { function NewActivityModal({ closeModal, submitActivity, submitFileActivity, chapterId }: any) {
const [selectedView, setSelectedView] = useState("home"); const [selectedView, setSelectedView] = useState("home");
return ( return (
<div> <div>
<button onClick={() => { setSelectedView("home") }}>
<ArrowLeftIcon />
</button>
<button onClick={closeModal}>
<Cross1Icon />
</button>
{selectedView === "home" && ( {selectedView === "home" && (
<ActivityChooserWrapper> <ActivityChooserWrapper>
<ActivityButton onClick={() => { setSelectedView("dynamic") }}>📄</ActivityButton> <ActivityOption onClick={() => { setSelectedView("dynamic") }}>
<ActivityButton onClick={() => { setSelectedView("video") }}>📹</ActivityButton> <ActivityTypeImage>
<Image alt="Dynamic Page" src={DynamicPageActivityImage}></Image>
</ActivityTypeImage>
<ActivityTypeTitle>Dynamic Page</ActivityTypeTitle>
</ActivityOption>
<ActivityOption onClick={() => { setSelectedView("video") }}>
<ActivityTypeImage>
<Image alt="Video Page" src={VideoPageActivityImage}></Image>
</ActivityTypeImage>
<ActivityTypeTitle>Video Page</ActivityTypeTitle>
</ActivityOption>
<ActivityOption onClick={() => { setSelectedView("video") }}>
<ActivityTypeImage>
<Image alt="Video Page" src={VideoPageActivityImage}></Image>
</ActivityTypeImage>
<ActivityTypeTitle>Video Page</ActivityTypeTitle>
</ActivityOption>
</ActivityChooserWrapper> </ActivityChooserWrapper>
)} )}
@ -30,30 +43,64 @@ function NewActivityModal({ closeModal, submitActivity, submitFileActivity, chap
{selectedView === "video" && ( {selectedView === "video" && (
<VideoModal submitFileActivity={submitFileActivity} chapterId={chapterId} /> <VideoModal submitFileActivity={submitFileActivity} chapterId={chapterId} />
)} )}
</div> </div>
); );
} }
const ActivityChooserWrapper = styled.div` const ActivityChooserWrapper = styled("div", {
display: flex; display: "flex",
flex-direction: row; flexDirection: "row",
align-items: center; justifyContent: "start",
justify-content: center; marginTop: 10,
gap: 20px; });
`;
const ActivityButton = styled.button` const ActivityOption = styled("div", {
padding: 40px; width: "180px",
border-radius: 10px !important; textAlign: "center",
border: none; borderRadius: 10,
font-size: 80px !important; background: "#F6F6F6",
margin: 40px; border: "4px solid #F5F5F5",
background-color: #8c949c33 !important; margin: "auto",
cursor: pointer;
&:hover { // hover
background-color: #8c949c7b; "&:hover": {
} cursor: "pointer",
`; background: "#ededed",
border: "4px solid #ededed",
transition: "background 0.2s ease-in-out, border 0.2s ease-in-out",
},
});
const ActivityTypeImage = styled("div", {
height: 80,
borderRadius: 8,
margin: 2,
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "end",
textAlign: "center",
background: "#ffffff",
// hover
"&:hover": {
cursor: "pointer",
},
});
const ActivityTypeTitle = styled("div", {
display: "flex",
fontSize: 12,
height: "20px",
fontWeight: 500,
color: "rgba(0, 0, 0, 0.38);",
// center text vertically
alignItems: "center",
justifyContent: "center",
textAlign: "center",
});
export default NewActivityModal; export default NewActivityModal;

View file

@ -1,4 +1,6 @@
import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/UI/Form/Form";
import React, { useState } from "react"; import React, { useState } from "react";
import * as Form from '@radix-ui/react-form';
function DynamicCanvaModal({ submitActivity, chapterId }: any) { function DynamicCanvaModal({ submitActivity, chapterId }: any) {
const [activityName, setActivityName] = useState(""); const [activityName, setActivityName] = useState("");
@ -22,14 +24,32 @@ function DynamicCanvaModal({ submitActivity, chapterId }: any) {
}); });
}; };
return ( return (
<div> <FormLayout onSubmit={handleSubmit}>
<div> <FormField name="dynamic-activity-name">
<input type="text" onChange={handleActivityNameChange} placeholder="Activity Name" /> <br /> <Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<input type="text" onChange={handleActivityDescriptionChange} placeholder="Activity Description" /> <FormLabel>Activity name</FormLabel>
<br /> <FormMessage match="valueMissing">Please provide a name for your activity</FormMessage>
<button onClick={handleSubmit}>Add Activity</button> </Flex>
</div> <Form.Control asChild>
</div> <Input onChange={handleActivityNameChange} type="text" required />
</Form.Control>
</FormField>
<FormField name="dynamic-activity-desc">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Activity description</FormLabel>
<FormMessage match="valueMissing">Please provide a description for your activity</FormMessage>
</Flex>
<Form.Control asChild>
<Textarea onChange={handleActivityDescriptionChange} required />
</Form.Control>
</FormField>
<Flex css={{ marginTop: 25, justifyContent: 'flex-end' }}>
<Form.Submit asChild>
<ButtonBlack type="submit" css={{ marginTop: 10 }}>Create Activity</ButtonBlack>
</Form.Submit>
</Flex>
</FormLayout>
); );
} }

View file

@ -1,4 +1,6 @@
import React from "react"; import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/UI/Form/Form";
import React, { useState } from "react";
import * as Form from '@radix-ui/react-form';
function VideoModal({ submitFileActivity, chapterId }: any) { function VideoModal({ submitFileActivity, chapterId }: any) {
const [video, setVideo] = React.useState(null) as any; const [video, setVideo] = React.useState(null) as any;
@ -21,16 +23,32 @@ function VideoModal({ submitFileActivity, chapterId }: any) {
and the actual upload isn't happening here anyway, it's in the submitFileActivity function */ and the actual upload isn't happening here anyway, it's in the submitFileActivity function */
return ( return (
<div> <FormLayout onSubmit={handleSubmit}>
<input type="text" placeholder="video title" onChange={handleNameChange} /> <FormField name="video-activity-name">
<br /> <Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<br /> <FormLabel>Video name</FormLabel>
<input type="file" onChange={handleVideoChange} name="video" id="" /> <FormMessage match="valueMissing">Please provide a name for your video activity</FormMessage>
<br /> </Flex>
<Form.Control asChild>
<Input onChange={handleNameChange} type="text" required />
</Form.Control>
</FormField>
<FormField name="video-activity-file">
<Flex css={{ alignItems: 'baseline', justifyContent: 'space-between' }}>
<FormLabel>Video file</FormLabel>
<FormMessage match="valueMissing">Please provide a video for your activity</FormMessage>
</Flex>
<Form.Control asChild>
<input type="file" onChange={handleVideoChange} required />
</Form.Control>
</FormField>
<br /> <Flex css={{ marginTop: 25, justifyContent: 'flex-end' }}>
<button onClick={handleSubmit}>Send</button> <Form.Submit asChild>
</div> <ButtonBlack type="submit" css={{ marginTop: 10 }}>Create Activity</ButtonBlack>
</Form.Submit>
</Flex>
</FormLayout>
); );
} }

View file

@ -2,6 +2,7 @@ import React from 'react';
import * as Dialog from '@radix-ui/react-dialog'; import * as Dialog from '@radix-ui/react-dialog';
import { styled, keyframes } from '@stitches/react'; import { styled, keyframes } from '@stitches/react';
import { violet, blackA, mauve, green } from '@radix-ui/colors'; import { violet, blackA, mauve, green } from '@radix-ui/colors';
import { ButtonBlack } from '../Form/Form';
type ModalParams = { type ModalParams = {
dialogTitle: string; dialogTitle: string;
@ -9,9 +10,10 @@ type ModalParams = {
dialogContent: React.ReactNode; dialogContent: React.ReactNode;
dialogClose?: React.ReactNode | null; dialogClose?: React.ReactNode | null;
dialogTrigger?: React.ReactNode; dialogTrigger?: React.ReactNode;
addDefCloseButton?: boolean;
onOpenChange: any; onOpenChange: any;
isDialogOpen?: boolean; isDialogOpen?: boolean;
minHeight?: "sm" | "md" | "lg" | "xl" minHeight?: "sm" | "md" | "lg" | "xl" | "no-min";
}; };
const Modal = (params: ModalParams) => ( const Modal = (params: ModalParams) => (
@ -39,6 +41,14 @@ const Modal = (params: ModalParams) => (
</Dialog.Close> </Dialog.Close>
</Flex> </Flex>
) : null} ) : null}
{params.addDefCloseButton ? (
<Flex css={{ marginTop: 25, justifyContent: 'flex-end' }}>
<Dialog.Close asChild>
<ButtonBlack type="submit" css={{ marginTop: 10 }}>Close</ButtonBlack>
</Dialog.Close>
</Flex>
) : null}
</DialogContent> </DialogContent>
</Dialog.Portal> </Dialog.Portal>
@ -80,6 +90,9 @@ const DialogContent = styled(Dialog.Content, {
variants: { variants: {
minHeight: { minHeight: {
'no-min': {
minHeight: '0px',
},
'sm': { 'sm': {
minHeight: '300px', minHeight: '300px',
}, },

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B