-
Notifications
You must be signed in to change notification settings - Fork 0
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
M-6 Activity Create UI #12
Changes from 2 commits
237380b
aabcbb9
eb91e11
f62e107
d1f92fb
129db0c
54dad88
cef4e86
5a08291
dc8d608
2aee48d
39fc7ef
774986a
6ae4700
765b074
1f8125f
28657c1
afadc75
7ce5437
b87a8bc
1b13037
10bfead
0c560fd
3d7c8b6
6683985
ca25316
1299b01
94d63a0
4cecdda
067a8f1
128fbc4
551d754
3da07b1
7f83955
56d73d1
a644b0b
fac749d
2be24e0
edd889f
0aa506e
7b8b64a
07cad6f
8d06e7a
11fb113
8f213f6
2596b9a
512eabe
c44b7cf
a90971e
8bb09d9
cf3e1de
c1ca210
2495ae5
d815286
b3de7f1
013d8ba
c5e56e8
5826f5a
e366c06
0d7cbd1
6a0a663
bffa2c7
19481d7
dc61a00
3407a71
8dc5753
dfcb458
105ac44
2f3c1f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import React, { useCallback, useState } from 'react' | ||
import { useDropzone } from 'react-dropzone' | ||
import { | ||
Box, | ||
Container, | ||
FormControl, | ||
FormLabel, | ||
Input, | ||
Button, | ||
Textarea, | ||
Image, | ||
SimpleGrid, | ||
Text, | ||
Flex | ||
} from '@chakra-ui/react' | ||
|
||
import { PrimaryButton } from '@/components/button' | ||
|
||
export const Form = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed the name to FormActivity! |
||
const [selectedImages, setSelectedImages] = useState<File[]>([]) | ||
|
||
const onDrop = useCallback((acceptedFiles: File[]) => { | ||
setSelectedImages((prevImages) => [...prevImages, ...acceptedFiles]) | ||
}, []) | ||
const { getRootProps, getInputProps } = useDropzone({ onDrop }) | ||
function removeImage(index: number) { | ||
setSelectedImages((prevImages) => { | ||
const newImages = [...prevImages] | ||
newImages.splice(index, 1) | ||
return newImages | ||
}) | ||
} | ||
|
||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => { | ||
event.preventDefault() | ||
|
||
const formData = new FormData(event.currentTarget) | ||
const title = formData.get('title') as string | ||
const address = formData.get('address') as string | ||
const timeFrom = formData.get('timeFrom') as string | ||
const timeTo = formData.get('timeTo') as string | ||
const url = formData.get('url') as string | ||
const memo = formData.get('memo') as string | ||
const cost = formData.get('cost') as string | ||
|
||
console.log({ | ||
title, | ||
address, | ||
timeFrom, | ||
timeTo, | ||
url, | ||
memo, | ||
cost, | ||
selectedImages | ||
}) | ||
} | ||
|
||
|
||
return ( | ||
<Container | ||
pt={{ base: '40px', md: '40px' }} | ||
pb={{ base: '40px', md: '80px' }} | ||
> | ||
<form onSubmit={handleSubmit}> | ||
<FormControl isRequired> | ||
<FormLabel>Title</FormLabel> | ||
<Input name="title" type="text" placeholder="Enter title" /> | ||
</FormControl> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>Address</FormLabel> | ||
<Input name="address" type="text" placeholder="Enter address" /> | ||
</FormControl> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>Time From</FormLabel> | ||
<Input name="timeFrom" type="time" /> | ||
</FormControl> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>Time To</FormLabel> | ||
<Input name="timeTo" type="time" /> | ||
</FormControl> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>URL</FormLabel> | ||
<Input name="url" type="url" placeholder="Enter URL" /> | ||
</FormControl> | ||
|
||
<Text mt={{ base: '30px', md: '40px' }} fontWeight="medium"> | ||
Image | ||
</Text> | ||
<SimpleGrid | ||
mt={{ base: '30px', md: '40px' }} | ||
columns={{ base: 2, md: 3 }} | ||
spacing={4} | ||
> | ||
{selectedImages.map((image, index) => ( | ||
<Image | ||
key={index} | ||
src={URL.createObjectURL(image)} | ||
alt={`Selected Image ${image.name}`} | ||
objectFit="cover" | ||
width={{ base: '160px', md: '180px' }} | ||
height={{ base: '106px', md: '120px' }} | ||
margin="auto" | ||
onClick={() => removeImage(index)} | ||
/> | ||
))} | ||
</SimpleGrid> | ||
|
||
<Box | ||
{...getRootProps()} | ||
textAlign="center" | ||
mt={{ base: '30px', md: '40px' }} | ||
> | ||
<PrimaryButton variant="outline"> | ||
<input {...getInputProps()} /> | ||
Add Image | ||
</PrimaryButton> | ||
</Box> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>Memo</FormLabel> | ||
<Textarea name="memo" placeholder="Enter memo" /> | ||
</FormControl> | ||
|
||
<FormControl mt={{ base: '30px', md: '40px' }}> | ||
<FormLabel>Cost</FormLabel> | ||
<Input name="cost" type="number" placeholder="Enter cost" /> | ||
</FormControl> | ||
|
||
|
||
<Flex justifyContent="center"> | ||
<Button | ||
mt={{ base: '30px', md: '40px' }} | ||
colorScheme="teal" | ||
type="submit" | ||
margin="auto" | ||
> | ||
Create Activity | ||
</Button> | ||
</Flex> | ||
</form> | ||
</Container> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {Form} from "./form" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
'use client' | ||
|
||
import { | ||
Box, | ||
Container, | ||
Heading, | ||
useColorModeValue | ||
} from '@chakra-ui/react' | ||
import { Header, Footer } from '@/components/navigation' | ||
import {Form} from "./components" | ||
|
||
|
||
export default function Create() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to name like |
||
|
||
const bg = useColorModeValue('white', 'gray.800') | ||
const color = useColorModeValue('black', 'gray.300') | ||
|
||
return ( | ||
<> | ||
<Box as="main" minH="100vh" bg={bg} color={color}> | ||
<Header /> | ||
<Container | ||
maxW={{ base: '100%', md: 'container.md' }} | ||
pt={{ base: '20px', md: '30px' }} | ||
pb={{ base: '40px', md: '80px' }} | ||
margin="auto" | ||
> | ||
<Container> | ||
<Heading as={'h1'} fontSize={{ base: '2xl', md: '4xl' }}> | ||
Create Activity | ||
</Heading> | ||
</Container> | ||
<Form /> | ||
</Container> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the extra container tags in page.tsx under the create directory, and removed container tags in form.tsx under the components directory. Could you please take a quick look and let me know if it looks good? |
||
<Footer /> | ||
</Box> | ||
</> | ||
) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made the title field required so that people can quickly add a new activity and add more information later.
I am unsure about how we are handling images. Are we storing images in the cloud and storing their CDN in the database? Currently, once images are added and the submit button is clicked, it stores image information like the example below: