Add base app
This commit is contained in:
85
components/domain/wishes/createWish/CreateWish.tsx
Normal file
85
components/domain/wishes/createWish/CreateWish.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { FC, FormEvent, SyntheticEvent, useState } from 'react'
|
||||
import { result } from '../../../common/result'
|
||||
import { createWish, Wish } from '../models'
|
||||
|
||||
interface CreateWishProps {
|
||||
onFocus: () => void
|
||||
onSubmit: (wish: Wish) => void
|
||||
}
|
||||
|
||||
const CreateWish: FC<CreateWishProps> = (props) => {
|
||||
const [focused, setFocused] = useState<boolean>(false)
|
||||
|
||||
const onSubmit = (e: SyntheticEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
const target = e.target as typeof e.target & {
|
||||
wishName: { value: string }
|
||||
wishDescription: { value?: string }
|
||||
wishLink: { value?: string }
|
||||
}
|
||||
|
||||
const wishRes = createWish(
|
||||
target.wishName.value,
|
||||
target.wishDescription.value,
|
||||
target.wishLink.value
|
||||
)
|
||||
|
||||
result.tap(wishRes, (wish) => {
|
||||
props.onSubmit(wish)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div onFocus={() => setFocused(true)}>
|
||||
<BasePrompt>
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="shadow p-4 space-y-6 bg-white">
|
||||
<div className="p-1 rounded space-y-6 bg-pink-100">
|
||||
<div className="bg-pink-100 transition-all">
|
||||
<input
|
||||
type="text"
|
||||
name="wishName"
|
||||
placeholder="Your wish!"
|
||||
className="appearance-none w-full bg-pink-100 text-lg text-center p-6 outline-none"
|
||||
/>
|
||||
<div className={focused ? 'block' : 'hidden'}>
|
||||
<InnerWishPrompt />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="py-2 px-4 bg-pink-400 rounded text-white"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</BasePrompt>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const InnerWishPrompt: FC = (props) => {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<textarea
|
||||
name="wishDescription"
|
||||
placeholder="Description"
|
||||
className="block appearance-none w-full resize-none rounded py-3 px-4 outline-none bg-pink-100"
|
||||
/>
|
||||
<div className="h-0.5 w-3/4 m-auto w-content bg-gray-300" />
|
||||
<input
|
||||
type="text"
|
||||
name="wishLink"
|
||||
placeholder="https://example.mywish"
|
||||
className="block appearance-none w-full rounded py-3 px-4 outline-none bg-pink-100"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const BasePrompt: FC = (props) => <div>{props.children}</div>
|
||||
|
||||
export default CreateWish
|
23
components/domain/wishes/models.ts
Normal file
23
components/domain/wishes/models.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { result } from '../../common/result'
|
||||
|
||||
export type Wish = {
|
||||
name: string
|
||||
description?: string
|
||||
link?: string
|
||||
}
|
||||
|
||||
export const createWish = (
|
||||
name: string,
|
||||
description?: string,
|
||||
link?: string
|
||||
): result.Result<Wish, string> => {
|
||||
if (typeof name !== 'undefined' && name.length > 0) {
|
||||
return result.ok({
|
||||
name,
|
||||
description,
|
||||
link,
|
||||
} as Wish)
|
||||
}
|
||||
|
||||
return result.err(`validation of wish failed via. createWish`)
|
||||
}
|
Reference in New Issue
Block a user