Squashed commit of the following:
commit 6304df307b853f9a30d06307a99a77bc3b0392f4 Author: Ivan Dimitrov <ivan@idimitrov.dev> Date: Wed Nov 15 23:16:35 2023 +0200 parcel lab case commit 3e0a3648ab998e4754427da08aa9c539f043f3b4 Author: Ivan Dimitrov <ivan@idimitrov.dev> Date: Wed Nov 15 19:46:28 2023 +0200 some more content commit e91a56dac8c1ed0f50964265406b329621f712f3 Author: Ivan Dimitrov <ivan@idimitrov.dev> Date: Wed Nov 15 18:49:21 2023 +0200 styles
This commit is contained in:
parent
57218bd8e2
commit
a3d71f7b42
198
_content/cases/parcellab.md
Normal file
198
_content/cases/parcellab.md
Normal file
@ -0,0 +1,198 @@
|
||||
---
|
||||
title: Parcel Lab integration into international eCommerce app
|
||||
goal: Integrate the Parcel Lab Post-purchase solution into all US and European WOSG websites
|
||||
role: Plan, design and implement the integration
|
||||
date: 2022 - 2023
|
||||
z: 2
|
||||
draft: false
|
||||
---
|
||||
|
||||
> parcelLab is the only truly global enterprise post-purchase software provider, enabling brands to increase top-line revenue, decrease operational costs, and optimize the customer experience.
|
||||
|
||||
|
||||
[Parcel Lab](https://parcellab.com/)
|
||||
|
||||
|
||||
Parcel lab takes care of the post-purchase operations like order tracking, email notifications, delivery status updates, data processing and more so that businesses don't have to.
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Technical overview
|
||||
|
||||
This integration is straightforward thanks to the [amazing documentation](https://how.parcellab.works/docs/) provided by the Parcel Lab team.
|
||||
|
||||
You really want to use the API even though there's more options to submit data to their platform.
|
||||
|
||||
The data model is based on the [tracking](https://how.parcellab.works/docs/onboarding/data-model) - a data object having four fields for the delivery information. An order is composed of one or more trackings.
|
||||
|
||||
Once data is submitted, the platform starts an automated process where it groups the new trackings to their respective orders and starts listening for events like
|
||||
"dispatch", "payment received" etc. to run custom actions. Each business can configure these events and actions so that they best match their operations.
|
||||
For example an "order created" event could notify the customer that the order has started as well as deal with some other business logic in the background.
|
||||
|
||||
Their [order status page](https://how.parcellab.works/docs/track-and-communicate/order-status-page) is a convenient script that you can configure for your website.
|
||||
The script reads the URL to find an order number so that it can fetch the most up-to-date information for that order and display it in an iFrame.
|
||||
|
||||
This system allows for a seamless, declarative event-based integration where the business takes care of the data and events (and sales) and parcelLab takes care of the rest.
|
||||
|
||||
---
|
||||
|
||||
### ParcelLab API details
|
||||
|
||||
Create the first order when a customer places it.
|
||||
|
||||
```hurl
|
||||
POST https://api.parcellab.com/order/ # This is the method and the endpoint
|
||||
user: business-uid # Header
|
||||
token: access-token # Header
|
||||
Content-Type: application/json # Header
|
||||
{ # Body starts here
|
||||
"xid": "id-of-delivery-before-tracking-number",
|
||||
"destination_country_iso3": "DEU",
|
||||
"client": "your-client-id",
|
||||
"orderNo": "order1", # This is the order ID
|
||||
"recipient": "Max Mustermann, parcelLab GmbH",
|
||||
"recipient_notification": "Max",
|
||||
"email": "max-mustermann@abc.xyz",
|
||||
"street": "Landwehrstr. 39",
|
||||
"zip_code": "80336",
|
||||
"city": "München",
|
||||
"billing_info": {
|
||||
"name": "Max",
|
||||
"phone": "1234",
|
||||
"street": "Nice St. 69",
|
||||
"city": "Nice",
|
||||
"zip_code": "69420",
|
||||
"country_iso3": "DEU"
|
||||
},
|
||||
"articles": [
|
||||
{
|
||||
"articleNo": "sku", # required
|
||||
"articleName": "Some Nice Thingy", # required
|
||||
"articleCategory": "Nice", # optional
|
||||
"articleUrl": "https://example.com/nice", # optional
|
||||
"articleImageUrl":"https://example.com/nice.png", # optional
|
||||
"quantity": 69, # optional
|
||||
},
|
||||
],
|
||||
"customFields": {
|
||||
"someField": {
|
||||
"anything": "in",
|
||||
"here": [],
|
||||
"nice": 69
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This will reflect on the parcelLab dashboard.
|
||||
|
||||
Add a few trackings to that order once you get the delivery number from the courier.
|
||||
|
||||
```hurl
|
||||
POST https://api.parcellab.com/track/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"tracking_number": "1",
|
||||
"courier": "dhl-germany",
|
||||
"zip_code": "12345",
|
||||
"deliveryNo": "1",
|
||||
"orderNo": "order1" # This references the above order
|
||||
}
|
||||
|
||||
POST https://api.parcellab.com/track/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"tracking_number": "2",
|
||||
"courier": "dhl-germany",
|
||||
"zip_code": "12345",
|
||||
"deliveryNo": "2",
|
||||
"orderNo": "order1"
|
||||
}
|
||||
|
||||
POST https://api.parcellab.com/track/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"tracking_number": "3",
|
||||
"courier": "dhl-germany",
|
||||
"zip_code": "12345",
|
||||
"deliveryNo": "3",
|
||||
"orderNo": "order1"
|
||||
}
|
||||
```
|
||||
|
||||
The order now has 3 trackings. Parcel Lab integrates with many couriers to provide status updates.
|
||||
|
||||
Update the order for whatever reason.
|
||||
|
||||
```hurl
|
||||
POST https://api.parcellab.com/order/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"orderNo": "order1",
|
||||
"customFields": {
|
||||
"customerPleased": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These updates can act as event notifications allowing for a declarative configuration.
|
||||
|
||||
```hurl
|
||||
POST https://api.parcellab.com/order/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"orderNo": "order1",
|
||||
"send_date": "now" # Gets notified that the order has been dispatched
|
||||
}
|
||||
```
|
||||
|
||||
Complete shipment.
|
||||
|
||||
```hurl
|
||||
POST https://api.parcellab.com/order/
|
||||
user: business-uid
|
||||
token: access-token
|
||||
Content-Type: application/json
|
||||
{
|
||||
"orderNo": "order1",
|
||||
"complete": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
All this can be viewed on the tracking page embedded anywhere.
|
||||
|
||||
```html
|
||||
<div id="parcellab-track-and-trace">
|
||||
<img src="https://cdn.parcellab.com/img/loading-spinner-1.gif" alt="loading" />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function plTrackAndTraceStart() {
|
||||
window.parcelLabTrackAndTrace.initialize({
|
||||
plUserId: TYPE_YOUR_USER_ID_HERE
|
||||
});
|
||||
var linkTag = document.createElement('link');
|
||||
linkTag.rel = 'stylesheet';
|
||||
linkTag.href = 'https://cdn.parcellab.com/css/v5/main.min.css';
|
||||
document.getElementsByTagName('head')[0].appendChild(linkTag);
|
||||
}
|
||||
</script>
|
||||
<script async onload="plTrackAndTraceStart()"
|
||||
src="https://cdn.parcellab.com/js/v5/main.min.js"></script>
|
||||
```
|
||||
|
||||
This shows a nice UI that can be [customized](https://how.parcellab.works/docs/track-and-communicate/order-status-page/configuration#additional-options).
|
||||
|
@ -3,7 +3,7 @@ title: Multi-tenant knowledge base website based on Google APIs
|
||||
goal: Create a modern multi-tenant web app that lets users use their Google Drive as a knowledge base
|
||||
role: Design and implement the web app
|
||||
date: Jul 29, 2023 - Nov 5, 2023
|
||||
z: 5
|
||||
z: 3
|
||||
---
|
||||
|
||||
This project aims to be a Google Drive frontend. It uses the Google APIs to fetch document data and display that data in a wiki-style web page.
|
||||
|
@ -7,5 +7,8 @@ z: 1
|
||||
draft: true
|
||||
---
|
||||
|
||||
[Wells Fargo](https://www.wellsfargo.com/) is a US based international financial institution operating in 35 countries and serving over 70 million people worldwide. [Source](https://en.wikipedia.org/wiki/Wells_Fargo)
|
||||
|
||||
|
||||
They provide an
|
||||
|
||||
|
13
_content/cases/wiki.hoi2bunker.com.md
Normal file
13
_content/cases/wiki.hoi2bunker.com.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Static wiki website powered by Markdown
|
||||
goal: Scrape an old wiki website and create a new one from the content
|
||||
role: Scrape, design and implement the app
|
||||
date: Jun 22, 2023 - Jun 27, 2023
|
||||
z: 6
|
||||
draft: true
|
||||
---
|
||||
|
||||
Repo: [github.com](https://github.com/hearts-of-iron-2/wiki)
|
||||
|
||||
This project aims to revamp an old, unmaintained wiki website and bring it back to life.
|
||||
|
@ -16,12 +16,15 @@
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
nvim = ide.nvim.${system} {
|
||||
plugins.lsp.servers = {
|
||||
plugins = {
|
||||
lsp.servers = {
|
||||
html.enable = true;
|
||||
tsserver.enable = true;
|
||||
jsonls.enable = true;
|
||||
tailwindcss.enable = true;
|
||||
};
|
||||
cmp-spell.enable = true;
|
||||
};
|
||||
};
|
||||
buildInputs = with pkgs; [
|
||||
coreutils-full
|
||||
|
@ -53,3 +53,7 @@
|
||||
@apply text-xl
|
||||
}
|
||||
|
||||
.md a {
|
||||
@apply underline text-teal-200 hover:text-cyan-500
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import rehypeHighlight from "rehype-highlight";
|
||||
import { notFound } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import CopyButton from "$components/copy-button";
|
||||
import { getText } from "@/app/lib/react";
|
||||
import { getText } from "$lib/react";
|
||||
|
||||
type Params = {
|
||||
slug: string[]
|
||||
@ -95,7 +95,7 @@ export default function Content({ params }: Props) {
|
||||
{role()}
|
||||
{date()}
|
||||
</div>
|
||||
<div className="w-full m-auto lg:w-3/4">
|
||||
<div className="w-full m-auto lg:w-3/4 mt-10">
|
||||
{ctnt()}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import Link from "next/link";
|
||||
import { getCases } from "../lib/content";
|
||||
import { getCases } from "$lib/content";
|
||||
|
||||
const Cases = () =>
|
||||
<div className="p-20 w-3/4 mx-auto flex flex-col gap-4">
|
||||
{getCases().filter(c => !c.data.draft).sort(c => Number(c.data.z)).reverse().map((c) => c.data).map((d) =>
|
||||
{getCases().filter(c => !c.data.draft).sort((a, b) => Number(b.data.z) - Number(a.data.z)).map((c) => c.data).map((d) =>
|
||||
<div key={d.slug} className="w-full h-max flex justify-center rounded-lg border-2">
|
||||
<Link className="btn flex flex-col w-full text-center" href={d.slug}>
|
||||
<span className="text-lg px-6">{d.title}</span>
|
||||
|
@ -5,6 +5,6 @@ export const getText = (node: ReactNode | any) => {
|
||||
if (!props) {
|
||||
return node
|
||||
}
|
||||
const c = props.children
|
||||
const c = props.children || ""
|
||||
return typeof c === "string" ? c : c.map(getText).join("")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user