Appearance
Components 📦 ​
Supersonic UI components. 🎉
All technical documentation for using these components can be found in the catalogue 📚.
Concepts ​
Augmenting packages with additional data through re-renders (cart):
One issue that comes as a result of seperating each piece of core functionality into it's own package (i.e the cart) means we do occasionally have to augment the data returned from these packages with our own view data and have this survive package re-renders.
A recent example of this occured when tooling out an Accordion component on the UI's which needed to remain open when editing combo options even as combo options were adjusted (casuing a re-render), the core of the implementation can be seen here.
The best pattern we have been able to distil here was to lift a simple state store to the view's provider level, pass the value and the setter to the view's hook and in this hook compute a new version of the cart options with the state data overtop via useMemo. In the above instance this allowed us to add both an active value and an activate function to each cart option when displaying these on the combo screen as accordions.
Generic Views: Generic views are intended to be used for views that can be used agnostically across a randge of products/domain i.e a "SMS Screen" will probably not change much in terms of design from a platform that handles clothing sales to one that handles food sales.
Domain Views: Domain views exist to ease further integrations, the intention here is that if we have a default restaurant interface and we want to onboard a new restaurant brand the intention is that 80% or more of the views should be able to come from the default restaurant interface.
To expand on this further a more nuanced example would be between a clothing interface and a restaurant interface in terms of products there are a lot of similarities (quantity, customisations, discounts, etc..) but in terms of the "typical" ordering experience the data is often presented differently.
As a rule of thumb a clothing store will put heavy emphasis on the "primary" product image and a lesser emphasis on customisations i.e color, this could be because customisations don't usually generate additional revenue in this space, however a typical restaurant interface will put a heavy emphasis on customisations (or upsells) as there is additional revenue oppurtunity.
With this in mind both interfaces essentially implement the same functionality but use it in very different ways, as a result it makes sense to maintain two different "domain" interfaces for both restaurants and clothing stores, this way when onboarding new clients in either space we should still be able to make use of 80% of the templates in the respective "domain" interface.
Structure ​
Atoms:
- Recoil
atomsfor the global store - These will not be exported by the
cringer.cataloguemodule
Hooks:
- These hooks are organized via domain (similar to the views)
- These will not be exported by the
cringer.cataloguemodule - Will contain shared logic used by the dedicated
hookorcontext
Views:
- Context
- Will invoke all
useState,useReducerand Recoil hooks. - Can receive props (will be retrieved via each dedicated
hook)
- Will invoke all
- Hook
- Will pull all state from respective
context - Will handle all reactive and computed data
- Will pull all state from respective
- View
- Will only ever invoke dedicated
hook - Will not receive any props (everything via
hook)
- Will only ever invoke dedicated
Assets:
- Contains all static CSS files and images
- These will not be exported by the
cringer.cataloguemodule
Layouts:
- These will wrap all views at the router level
- Will contain common components like
HeaderandFooter - Will allow the user to override common components without having to override and entire view
Services:
- XState service definitions
- These will not be exported by the
cringer.cataloguemodule
Components:
- Stateless
- Will not invoke any internal hooks
- Will only recieve display data as props
- Views will provide all display data required by components
- Stateful
- Will recieve all display data as props
- Will invoke a hook to manage internal state
- Views will provide all display data required by components
Gotcha's 💥 ​
Because we are using Tailwind 2 we need to run a compatability layer for autoprefixer.
We have decided to not cache settings and menu for the following reasons:
- Caching is not relevant on kiosks
- Mobile caching can either be fast and wrong or slow and right
- Industry standard for e-commerce is usually to re-valuate requests
- Allows us to validate the cached cart against menu on each refresh and report newly invalid products
- Mobile users wont really benefit from any scheduled check as theyre most likely first timers or have large amounts of time between app usage