import { h, Html, Rx } from 'lib/rx'
import * as rx from 'lib/rx'
import * as request from 'request'
import * as modal from 'ui/modal'
import * as layout from 'ui/layout'
import * as markerModel from 'models/marker'
import * as form from 'lib/form'
import * as icons from 'lib/icons'
import * as L from 'lib/loadable'
interface MarkerFormParams {
lat: number
lng: number
marker?: markerModel.Marker
colors: Array
label: string
req: (body: string) => Promise
onSuccess: (m: markerModel.Marker) => void
onClose: () => void
lastUserAdded?: markerModel.Marker
onDeleteMarker?: () => void
}
export function view({ lat, lng, marker, colors, label, req, onSuccess, onClose, lastUserAdded, onDeleteMarker }: MarkerFormParams): Html {
const initName = marker?.name || ''
const initDescription = marker?.description || ''
const initColor = marker?.color || lastUserAdded?.color || (colors.length > 0 ? colors[0] : '#3584e4')
const initIcon = marker?.icon || ''
const initRadius = marker?.radius || 0
const isCreation = marker === undefined
const iconValues: { [key: string]: string } = {}
Object.keys(icons.values).forEach(key => iconValues[key] = icons.values[key].name)
return modal.view({
header: marker == undefined ? 'Nouveau marqueur' : 'Modification du marqueur',
body: rx.withState7, L.Loadable>(
[initName, initDescription, initColor, initIcon, initRadius, L.init, L.init],
(nameVar, descriptionVar, colorVar, iconVar, radiusVar, updateReqVar, deleteReqVar) =>
h('form',
{
onsubmit: rx.map5([nameVar, descriptionVar, colorVar, iconVar, radiusVar], (name, description, color, icon, radius) =>
(event: Event) => {
event.preventDefault()
updateReqVar.update(_ => L.loading)
const payload = { lat, lng, color, name, description, icon, radius }
req(JSON.stringify(payload))
.then((m: markerModel.Marker) => {
updateReqVar.update(_ => L.loaded(undefined))
onSuccess(m)
})
.catch(({ message }) => updateReqVar.update(_ => L.failure(message)))
}
)
},
form.input({
label: 'Nom',
select: isCreation,
initValue: initName,
onUpdate: value => {
nameVar.update(_ => value)
updateReqVar.update(_ => L.init)
deleteReqVar.update(_ => L.init)
}
}),
form.textarea({
label: 'Description',
initValue: initDescription,
onUpdate: value => {
descriptionVar.update(_ => value)
updateReqVar.update(_ => L.init)
deleteReqVar.update(_ => L.init)
}
}),
colorSection({
colorRx: colorVar,
colors,
onUpdateColor: color => {
colorVar.update(_ => color)
updateReqVar.update(_ => L.init)
deleteReqVar.update(_ => L.init)
}
}),
layout.columns([
form.select({
label: 'IcĂ´ne',
initValue: initIcon,
values: iconValues,
onUpdate: value => {
iconVar.update(_ => value)
updateReqVar.update(_ => L.init)
deleteReqVar.update(_ => L.init)
}
}),
form.input({
type: 'number',
label: 'Radius',
initValue: initRadius.toString(),
onUpdate: value => {
radiusVar.update(_ => parseInt(value) || 0)
updateReqVar.update(_ => L.init)
deleteReqVar.update(_ => L.init)
}
})
]),
form.error(updateReqVar),
form.error(deleteReqVar),
form.submit({
label,
className: 'g-Button--FullWidth',
requestVar: updateReqVar,
disabled: deleteReqVar.map(l => l != L.init)
}),
marker !== undefined && onDeleteMarker !== undefined && form.button({
style: 'margin-top: 1rem',
label: 'Supprimer',
className: 'g-Button--FullWidth g-Button--Danger',
requestVar: deleteReqVar,
disabled: updateReqVar.map(l => l != L.init),
onClick: () => {
deleteReqVar.update(_ => L.loading)
request
.del_(`/api/markers/${marker.id}`)
.then(_ => onDeleteMarker())
.catch(({ message }) => updateReqVar.update(_ => L.failure(message)))
}
})
)
),
onClose: onClose
})
}
interface ColorSectionParams {
colorRx: Rx,
colors: Array,
onUpdateColor: (color: string) => void,
}
function colorSection({ colorRx, colors, onUpdateColor }: ColorSectionParams): Html {
return h('label',
{ className: 'g-Label' },
'Couleur',
h('div',
{ className: 'g-ColorLine' },
h('input',
{
type: 'color',
className: 'g-Input',
oninput: (event: Event) => onUpdateColor((event.target as HTMLInputElement).value),
value: colorRx
}
),
h('div',
{ className: 'g-ColorButtons' },
colors.map(c =>
h('input',
{
type: 'button',
className: 'g-ColorButton',
style: `background-color: ${c}`,
onclick: (event: Event) => onUpdateColor(c)
}
)
)
)
)
)
}