diff --git a/api/items.js b/api/items.js index 7916d15..f8d1ac9 100644 --- a/api/items.js +++ b/api/items.js @@ -24,7 +24,7 @@ router.get('/', async (req, res) => { res.json(items) }) -const newItemValidators = [ +const itemValidators = [ validate.validUrlSlug('urlslug'), validate.publishedBool, validate.positiveInteger('price_cents'), @@ -33,7 +33,7 @@ const newItemValidators = [ validate.handleApiError ] -router.post('/', parseJSON, newItemValidators, async (req, res) => { +router.post('/', parseJSON, itemValidators, async (req, res) => { const item = await db.item.create( req.body.name, req.body.urlslug, @@ -50,6 +50,19 @@ router.get('/by-slug/:slug', async (req, res) => { res.json(item) }) +router.post('/:uuid', parseJSON, itemValidators, async (req, res) => { + const item = await db.item.update( + req.params.uuid, + req.body.name, + req.body.urlslug, + req.body.description, + req.body.price_cents, + req.body.published + ) + + res.json(item) +}) + router.post('/:uuid/images', upload.single('image'), async (req, res) => { // Handle either image upload body or JSON body try { diff --git a/db/models/item.js b/db/models/item.js index 1ad3e14..038789d 100644 --- a/db/models/item.js +++ b/db/models/item.js @@ -69,6 +69,25 @@ item.create = async (name, urlslug, description, price_cents, published) => { return joinjs.map(rows, mappings, 'itemMap', 'item_')[0] } +item.update = async (uuid, name, urlslug, description, price_cents, published) => { + const query = { + text: 'select * from sos.update_item($1::uuid, $2::text, $3::citext, $4::text, $5::integer, $6::boolean)', + values: [ + uuid, + name, + urlslug, + description, + price_cents, + published + ] + } + + debug(query) + + const {rows} = await pg.query(query) + return joinjs.map(rows, mappings, 'itemMap', 'item_')[0] +} + item.addImage = async (item_uuid, image_buffer, uploader_uuid) => { // Default param chain: output as png diff --git a/db/sql/3-functions.sql b/db/sql/3-functions.sql index b4c6b6c..3be1baf 100644 --- a/db/sql/3-functions.sql +++ b/db/sql/3-functions.sql @@ -105,6 +105,28 @@ begin return query select * from sos.v_item where item_uuid = _item_uuid; end; $function$; +create or replace function sos.update_item(_uuid uuid, _name text, _urlslug citext, _description text, _price_cents integer, _published boolean) + returns setof sos.v_item + language plpgsql +as $function$ +begin + update sos."item" set ( + item_name, + item_urlslug, + item_description, + item_price_cents, + item_published + ) = ( + _name, + _urlslug, + _description, + _price_cents, + _published + ) where item_uuid = _uuid; + + return query select * from sos.v_item where item_uuid = _uuid; +end; $function$; + create or replace function sos.add_image_to_item(_item_uuid uuid, _large_file bytea, _thumb_file bytea, _mime_type varchar, _uploader_uuid uuid) returns setof sos.v_item language plpgsql diff --git a/pages/admin/items/[slug].js b/pages/admin/items/[slug].js index 405bfce..5956bf7 100644 --- a/pages/admin/items/[slug].js +++ b/pages/admin/items/[slug].js @@ -1,4 +1,5 @@ import React from 'react' +import router from 'next/router' import {FormController, Input, DecimalInput, Button, Checkbox} from '~/components/form' EditItem.getInitialProps = async ({ctx: {axios, query: {slug}}}) => { @@ -15,10 +16,14 @@ export default function EditItem({item}) { return true; } + const afterUpdate = (item) => { + router.replace(`/admin/items/${item.urlslug}`) + } + return ( <>