Marketplaces

Image for post
Image for post

A marketplace consists of supply — provided by sellers and demand — created by buyers.

A marketplace matches buyers with sellers.

We consider real or virtual goods (items). We do not consider here service marketplaces such as Uber.

A fundamental function of the marketplace is the pricing of items transacted through the market.

What mechanism can the marketplace use to set the price of the items sold through the market?

Pricing of Items


Image for post
Image for post

Building a web site for an auction, we wanted an infinite scroll of lots as many lots where expected.

The web application is a Laravel project with Livewire for the views.

The Livewire Component

The list of lots is a Livewire component:

<?php

namespace App\Http\Livewire\Catalogue\Lot;

use Livewire\Component;
use Illuminate\Database\Eloquent\Builder;

use App\Lot;
use App\Auction;

class LotList extends Component
{
public $count;
}

$count tracks the number of lots to show on the screen.

We render the view with:

public function render()
{
return view('livewire.catalogue.lot.lot-list', [
'subdomain' => $this->subdomain,
]);
}

Using the computed property,

public function getLotsProperty()
{
$query = Lot::query();

$lots = $query
->orderBy('updated_at', 'asc')
->take($this->count)
->get();
return $lots…


Image for post
Image for post

For all of you Bootstrap, developers who need to construct a multi-step form in React, here is this simple one.

It was built with Create React App and uses React Hooks and Bootstrap 4.

It displays a linear progress bar at the top. The user fills the details in stages, followed by GDPR information and a Thank You stage.

It is a single component where each stage is rendered according to the stage counter,

{
stage === 4 && ...
}

App.js

import React, { useState } from 'react';
import './App.css';

const stages = ['name', 'contact', 'gdpr', 'thanks'];

function App() {
const [stage, setStage] = useState(0);

const [details, setDetails] = React.useState({
firstName: '',
lastName: '',
email: '',
phone: '',
acceptGDPR: false
});

const processField = (name, value) => {
setDetails({ ...details, [name]: value });
}

return (
<div className="container">
<h1>Register</h1>
<div className="progress mt-3 mb-3">
<div className="progress-bar" role="progressbar" style={{ width: `${ (stage + 1) / stages.length * 100 }%` }} aria-valuenow={ (stage + 1) / stages.length * 100 } aria-valuemin="0" aria-valuemax="100"></div>
</div>
{
stage === 0 &&
<form>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<input
type="text"
className="form-control"
id="firstName"
aria-describedby="firstNameHelp"
value={details.firstName}
onChange={e => processField('firstName', e.target.value)}
/>
<small id="firstNameHelp" className="form-text text-muted">Required</small>
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<input
type="text"
className="form-control"
id="lastName"
aria-describedby="lastNameHelp"
value={details.lastName}
onChange={e => processField('lastName', e.target.value)}
/>
<small id="lastNameHelp" className="form-text text-muted">Required</small>
</div>
<button
type="button"
className="btn btn-primary"
disabled={ !details.firstName && !details.lastName }
onClick={ () => setStage(stage + 1) }
style={{ opacity: !details.firstName && !details.lastName ? 0.2 : 1 }}
>
Next
</button>
</form>
}
{
stage === 1 &&
<form>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
type="text"
className="form-control"
id="email"
aria-describedby="emailHelp"
value={details.email}
onChange={e => processField('email', e.target.value)}
/>
<small id="emailHelp" className="form-text text-muted">Required</small>
</div>
<div className="form-group">
<label htmlFor="phone">Phone</label>
<input
type="text"
className="form-control"
id="phone"
aria-describedby="phoneHelp"
value={details.phone}
onChange={e => processField('phone', e.target.value)}
/>
<small id="phoneHelp" className="form-text text-muted">Optional</small>
</div>
<button
type="button"
className="btn btn-primary"
disabled={ !details.email }
onClick={ () => setStage(stage + 1) }
style={{ opacity: !details.email ? 0.2 : 1 }}
>
Next
</button>
</form>
}
{
stage === 2 &&
<form>
<blockquote className="blockquote mt-3 mb-3">
<p className="mb-0">GDPR protects your data for sure ...</p>
</blockquote>
<div className="form-check mt-3 mb-3">
<input
className="form-check-input"
type="checkbox"
value={ details.acceptGDPR }
id="acceptGDPR"
onChange={e => setDetails({ ...details, acceptGDPR: e.target.value })}
/>
<label className="form-check-label" htmlFor="acceptGDPR">
Accept
</label>
</div>
<button
type="button"
className="btn btn-primary"
disabled={ !details.acceptGDPR }
onClick={ () => setStage(stage + 1) }
style={{ opacity: !details.acceptGDPR ? 0.2 : 1 }}
>
Next
</button>
</form>
}
{
stage === 3 &&
<div>
<div className="alert alert-success mt-3 mb-3" role="alert">
Thank You - { details.firstName }
</div>

<h2>Your Recorded Details</h2>

<dl className="row">
<dt className="col-sm-3">First Name</dt>
<dd className="col-sm-9">{ details.firstName }</dd>

<dt className="col-sm-3">Last Name</dt>
<dd className="col-sm-9">{ details.lastName }</dd>

<dt className="col-sm-3">Email</dt>
<dd className="col-sm-9">{ details.email }</dd>

<dt className="col-sm-3">Phone</dt>
<dd className="col-sm-9">{ details.phone …

Image for post
Image for post

Laravel-medialibrary is a Laravel package for associating all sorts of files with Eloquent models.

We have an Auction model that uses the library to associate an image with each object,

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Auction extends Model implements HasMedia
{
use HasFactory;

use InteractsWithMedia;
}

We wanted to seed an Eloquent model that has associated images using a seeder AuctionSeeder:

class AuctionSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Auction::factory()
->count(10)
->create();
}
}

running a factory AuctionFactory,

namespace Database\Factories;

use App\Models\Auction;

use Illuminate\Database\Eloquent\Factories\Factory;

class AuctionFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Auction::class;

/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => Str::substr($this->faker->words(5, true), 0, 30),
'description' => $this->faker->text(600),
]…

NFC Tags are used extensively in agri-tech, warehouse, and logistics operations to track real-life objects.

With COVID-19, contactless technology has acquired importance in commercial and consumer applications. We see a need to scan NFC tags with mobile applications beyond the above well-known industrial applications.

Image for post
Image for post

Cordova

Cordova is a cross-platform mobile framework for apps in Android and iOS. Building a Cordova mobile app is easy for web developers as it uses the standard HTML, CSS, and JavaScript technologies. One use either plain JavaScript or one of the more expressive Single Page Application (SPA) frameworks, such as React, Vue, or Angular.

While Cordova may seem like a browser packaged in a mobile app, it is quite powerful in contactless technology in general and NFC in particular. …


Electron is a cross-platform framework for building desktop apps with JavaScript, HTML, and CSS.

In agricultural, industrial, and logistics integrated facilities, such desktop apps often need to read information from barcodes and QR codes printed on real-life physical objects.

Image for post
Image for post
QR Code
Image for post
Image for post
Barcode

Such barcodes and QR codes are scanned with a barcode scanner such as Zebra DS4305 Digital Scanner connected to the computer with a USB connector.

Image for post
Image for post
Scanner

Receiving the code into the Electron app turns up to be very simple. The scanner is viewed as a keyboard.

So if you have in the HTML an input element,

<input id="codeInput"/>

And we focus the program on the input field, using JavaScript,

document.getElementById("codeInput").focus();

The scanner reads the code into the input field like it was typed in by the keyboard.


Photo by mariananbu on Pixabay
Photo by mariananbu on Pixabay

In an online auction project, the users were spread in a variety of time zones. Each had to see the accurate time for the end of the auction, while some users would create auctions from the web page. This required us to juggle timezones at the front-end and the backend.

Dates, Times, and Time Zones

A user of a web application has to see the dates and times in his/her local time zone. These dates and times in a SPA, or dynamically rendered parts of a we page, are obtained by JavaScript from the browser, using new Date(dateString)

This dateString comes from the server, so the question is how is it stored. …


Photo by QuinceCreative on Pixabay
Photo by QuinceCreative on Pixabay

An auction system either live or timed runs by the clock. In a live auction, one often runs calls on a bid according to a clock. In a timed auction, you start and end an auction by the clock, and you show the users a countdown timer.

Browser Times Cannot Be Trusted

In a browser, new Date() gives you the user local time, according to the user's computer local time. As users reside in different time zones, and moreover may have inaccurate computer clock, or they may just intentionally modify that clock, the local time will be different.

Obviously, one cannot let the user observe any time-dependent functionality, and make any time-dependent action, based on a clock which is the same for all users of the auction system. …


Photo by alexseynemiro on Pixabay
Photo by alexseynemiro on Pixabay

It used to be the case that when you program a Laravel project, you program in PHP within the Laravel framework, and then have Vue.js or some other front-end framework at the front-end.

The rise of the TALL stack — Tailwind CSS, Alpine.js, LiveWire, Laravel — has grossly diminished the role of front-end frameworks, specifically through the use of Livewire to program in Laravel-speak much of the dynamic aspects of the front-end.

The integration of ReactPHP into Laravel for web sockets in Laravel Websockets, eliminated the need to use the Laravel Echo Server server and more generally Node.js


Photo by nile on Pixabay
Photo by nile on Pixabay

In many applications such as auctions, you need a dynamic collection of timers, such that you can add timers, and cancel timers.

We found ReactPHP superior for this. This sweet and simple server sets a new timer specified by a timeout and a task to be performed on timeout. For example sake, the task is just a string to be printed.

The server has three endpoints:

  • GET /timers - list the active timers
  • POST /add - add a timer, and returns a timer index for future reference
  • POST /cancel - delete a timer by its index

Assuming you have installed ReactPHP…

About

Yoram Kornatzky

Open source, Mobile, Web, Cloud, Server - Independent Information Technology and Services Professional http://yoramkornatzky.com kornatzky@gmail.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store