Skip to content

Commit

Permalink
Episodio 10
Browse files Browse the repository at this point in the history
  • Loading branch information
durancristhian committed Sep 22, 2020
1 parent fb4c98c commit f105602
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 69 deletions.
150 changes: 83 additions & 67 deletions components/CreateChallenge.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useCollection } from '@nandorojo/swr-firestore'
import { ErrorMessage, Field, FieldArray, Form, Formik } from 'formik'
import { Field, FieldArray, Form, Formik, getIn, FormikValues } from 'formik'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { v4 as uuidv4 } from 'uuid'
import * as Yup from 'yup'
import { useUser } from '../hooks/useAuth'
import CheckCircle from '../icons/CheckCircle'
import XCircle from '../icons/XCircle'
import { Game, Question } from '../types/Game'
import Button from '../ui/Button'
import Heading from '../ui/Heading'
Expand All @@ -15,6 +17,19 @@ type InitialValue = {
questions: Question[]
}

const ErrorMessage = ({ name }: { name: string }) => (
<Field name={name}>
{({ form }: { form: FormikValues }) => {
const error = getIn(form.errors, name)
const touch = getIn(form.touched, name)

return touch && error ? (
<div className="text-red-500 mt-1">{error}</div>
) : null
}}
</Field>
)

const initialValues: InitialValue = {
name: '',
description: '',
Expand Down Expand Up @@ -65,39 +80,44 @@ const CreateChallenge = () => {
</div>
<Formik
initialValues={{ ...initialValues }}
validationSchema={Yup.object({
validationSchema={Yup.object().shape({
name: Yup.string()
.max(140, 'Must be 140 characters or less')
.required('Required'),
.required('Required')
.max(140, 'Must be 140 characters or less'),
description: Yup.string()
.max(280, 'Must be 280 characters or less')
.required('Required'),
questions: Yup.array().min(1),
/* .of(
Yup.object({
.required('Required')
.max(280, 'Must be 280 characters or less'),
questions: Yup.array()
.min(1)
.of(
Yup.object().shape({
id: Yup.string().required('Required'),
description: Yup.string()
.max(280, 'Must be 280 characters or less')
.required('Required'),
.required('Required')
.max(280, 'Must be 280 characters or less'),
time: Yup.mixed().oneOf(['30', '60', '120']),
validOption: Yup.string().required('Required'),
options: Yup.array()
.min(4)
.max(4)
.of(
Yup.object({
id: Yup.string().required('Required'),
content: Yup.string()
.max(280, 'Must be 280 characters or less')
.required('Required'),
}),
),
options: Yup.array().of(
Yup.object().shape({
id: Yup.string().required('Required'),
content: Yup.string()
.required('Required')
.max(280, 'Must be 280 characters or less'),
}),
),
}),
), */
),
})}
onSubmit={onSubmit}
>
{({ dirty, isValidating, isValid, isSubmitting, values }) => (
{({
dirty,
isValidating,
isValid,
isSubmitting,
values,
setFieldValue,
}) => (
<Form>
<div className="mb-4">
<Field
Expand All @@ -106,10 +126,7 @@ const CreateChallenge = () => {
className="border-2 px-4 py-2 focus:outline-none focus:shadow-outline w-full mb-1"
placeholder="Name"
/>
<ErrorMessage
name="name"
render={(msg) => <div className="text-red-500">{msg}</div>}
/>
<ErrorMessage name="name" />
</div>
<div className="mb-4">
<Field
Expand All @@ -118,10 +135,7 @@ const CreateChallenge = () => {
className="border-2 px-4 py-2 focus:outline-none focus:shadow-outline w-full mb-1"
placeholder="Description"
/>
<ErrorMessage
name="description"
render={(msg) => <div className="text-red-500">{msg}</div>}
/>
<ErrorMessage name="description" />
</div>
<div className="mb-4">
<FieldArray
Expand All @@ -138,24 +152,24 @@ const CreateChallenge = () => {
push({
id: uuidv4(),
description: '',
time: 30,
time: '30',
validOption: defaultValidOption,
options: [
{
id: defaultValidOption,
content: 'Option 1',
content: '',
},
{
id: uuidv4(),
content: 'Option 2',
content: '',
},
{
id: uuidv4(),
content: 'Option 3',
content: '',
},
{
id: uuidv4(),
content: 'Option 4',
content: '',
},
],
})
Expand All @@ -174,10 +188,7 @@ const CreateChallenge = () => {
placeholder="Description"
/>
<ErrorMessage
name={`questions.${questionIndex}.description`}
render={(msg) => (
<div className="text-red-500">{msg}</div>
)}
name={`questions[${questionIndex}].description`}
/>
</div>
<div className="mb-4">
Expand All @@ -191,35 +202,44 @@ const CreateChallenge = () => {
<option value="60">60 seconds</option>
<option value="120">120 seconds</option>
</Field>
<ErrorMessage
name={`questions.${questionIndex}.time`}
render={(msg) => (
<div className="text-red-500">{msg}</div>
)}
/>
</div>
{question.options.map((option, optionIndex) => (
<div key={option.id} className="mb-4">
<Field
name={`questions.${questionIndex}.options.${optionIndex}.content`}
type="text"
className="border-2 px-4 py-2 focus:outline-none focus:shadow-outline w-full mb-1"
placeholder="Option content"
/>
<div className="flex items-center">
<div className="flex-auto">
<Field
name={`questions.${questionIndex}.options.${optionIndex}.content`}
type="text"
className="border-2 px-4 py-2 focus:outline-none focus:shadow-outline w-full mb-1"
placeholder={`Option content #${
optionIndex + 1
}`}
/>
</div>
<div className="ml-4">
<button
type="button"
className="focus:outline-none focus:shadow-outline"
onClick={() => {
setFieldValue(
`questions.${questionIndex}.validOption`,
option.id,
)
}}
>
{question.validOption === option.id ? (
<CheckCircle className="h-6 text-green-500" />
) : (
<XCircle className="h-6 text-red-500" />
)}
</button>
</div>
</div>
<ErrorMessage
name={`questions.${questionIndex}.options.${optionIndex}.content`}
render={(msg) => (
<div className="text-red-500">{msg}</div>
)}
name={`questions[${questionIndex}].options[${optionIndex}].content`}
/>
</div>
))}
<ErrorMessage
name={`questions.${questionIndex}.options`}
render={(msg) => (
<div className="text-red-500">{msg}</div>
)}
/>
<Button
type="button"
onClick={() => {
Expand All @@ -233,10 +253,6 @@ const CreateChallenge = () => {
</div>
)}
/>
<ErrorMessage
name="questions"
render={(msg) => <div className="text-red-500">{msg}</div>}
/>
</div>
<div className="text-center">
<Button
Expand Down
12 changes: 10 additions & 2 deletions pages/games/[gameId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,17 @@ function Table({ gameId, isAdmin }: TableProps) {

const exportCSV = (players: Player[]) => {
const csv = players.map((p) => `${p.name},${p.email},${p.score}`).join('\n')
const dl = 'data:text/csv;charset=utf-8,' + csv
const csvContent = encodeURI(csv)

window.open(encodeURI(dl))
const elem = window.document.createElement('a')
elem.href = 'data:text/csv;charset=utf-8,' + csvContent
elem.download = 'podium.csv'

document.body.appendChild(elem)

elem.click()

document.body.removeChild(elem)
}

return (
Expand Down

1 comment on commit f105602

@vercel
Copy link

@vercel vercel bot commented on f105602 Sep 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.