Compare commits
	
		
			34 Commits
		
	
	
		
			ci-cd-depl
			...
			ac387d41ad
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ac387d41ad | |||
| 2654b4a9c4 | |||
| f152476d8f | |||
| 26eb75646b | |||
| 8473d0d4d6 | |||
| 0d646c5d6b | |||
| a74de768ac | |||
| cc5879e0a8 | |||
| afccda0eb9 | |||
| 7f5b8e7aa5 | |||
| 5ac899e9d9 | |||
| 809db72f56 | |||
| b4c79e8772 | |||
| efdb0f2593 | |||
| a91ce41978 | |||
| 4372e6592a | |||
| 89a1f49ff6 | |||
| 024267c5ca | |||
| c683ad2752 | |||
| c373970058 | |||
| 105c068f62 | |||
| e7db1595c8 | |||
| c8455ed31f | |||
| 6836f05d06 | |||
| a5489801ba | |||
| 7ad3901960 | |||
| 76888be1b9 | |||
| 057c3393a4 | |||
| 23a8bf752d | |||
| f354eda75a | |||
| a016159bab | |||
| 637089aa42 | |||
| 920def3123 | |||
| 0df02e995d | 
@ -17,6 +17,7 @@ steps:
 | 
				
			|||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
      STACK_NAME: kios_admin_lumbung_space
 | 
					      STACK_NAME: kios_admin_lumbung_space
 | 
				
			||||||
      SECRET_PAYLOAD_SECRET_VERSION: v1
 | 
					      SECRET_PAYLOAD_SECRET_VERSION: v1
 | 
				
			||||||
 | 
					      APP_ENTRYPOINT_VERSION: v1
 | 
				
			||||||
    settings:
 | 
					    settings:
 | 
				
			||||||
      stack: kios_admin_lumbung_space
 | 
					      stack: kios_admin_lumbung_space
 | 
				
			||||||
      host: lumbung.space
 | 
					      host: lumbung.space
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					MONGODB_URI=
 | 
				
			||||||
 | 
					PAYLOAD_SECRET=
 | 
				
			||||||
 | 
					# local
 | 
				
			||||||
 | 
					PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
 | 
				
			||||||
 | 
					# Production
 | 
				
			||||||
 | 
					# PAYLOAD_PUBLIC_SERVER_URL=https://kios-admin.lumbung.space
 | 
				
			||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -38,6 +38,7 @@ bower_components
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
 | 
					# Compiled binary addons (https://nodejs.org/api/addons.html)
 | 
				
			||||||
build/Release
 | 
					build/Release
 | 
				
			||||||
 | 
					build/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Dependency directories
 | 
					# Dependency directories
 | 
				
			||||||
node_modules/
 | 
					node_modules/
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								.yarnrc.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.yarnrc.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					nodeLinker: node-modules
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
FROM node:18-alpine as base
 | 
					FROM node:21-bookworm as base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM base as builder
 | 
					FROM base as builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								README.md
									
									
									
									
									
								
							@ -1,9 +1,25 @@
 | 
				
			|||||||
# lumbung-kiosk-cms
 | 
					# lumbung-kiosk-cms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This project was created using create-payload-app using the ts-blank template.
 | 
					[](https://drone.autonomic.zone/ruangrupa/lumbung-kios-cms)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## How to Use
 | 
					This project was created using `npx create-payload-app` using the ts-blank template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`yarn dev` will start up your application and reload on any changes.
 | 
					## Local development
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- First, create a `.env` file in the root, and populate it with these values:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					MONGODB_URI=mongodb://mongo:27017/lumbung-kios-cms
 | 
				
			||||||
 | 
					PAYLOAD_SECRET=5c8ac4a2cd754247f38ae726
 | 
				
			||||||
 | 
					PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Run `docker-compose -f docker-compose-local.yml up` to get the application running locally.
 | 
				
			||||||
 | 
					- The application will have no data by default, so you will have to create your own test products, couriers, retailers, dispatches, and makers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Deployment & production setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Push commits, it will auto-deploy to [kios-admin.lumbung.space](https://kios-admin.lumbung.space). CI/CD is powered by [Drone](https://drone.autonomic.zone/ruangrupa/lumbung-kios-cms), it uses the `Dockerfile` in the root project folder for builds. You can test builds locally using `docker build .`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The application is running on the `ruangrupa-dedi` server as a vanilla Docker swarm stack.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you have docker and docker-compose installed, you can run `docker-compose up`
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								compose.yml
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								compose.yml
									
									
									
									
									
								
							@ -6,6 +6,7 @@ services:
 | 
				
			|||||||
    image: decentral1se/kios-admin:latest
 | 
					    image: decentral1se/kios-admin:latest
 | 
				
			||||||
    networks:
 | 
					    networks:
 | 
				
			||||||
      - proxy
 | 
					      - proxy
 | 
				
			||||||
 | 
					      - internal
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - app:/home/node/app
 | 
					      - app:/home/node/app
 | 
				
			||||||
      - node_modules:/home/node/app/node_modules
 | 
					      - node_modules:/home/node/app/node_modules
 | 
				
			||||||
@ -14,10 +15,14 @@ services:
 | 
				
			|||||||
      PORT: 3000
 | 
					      PORT: 3000
 | 
				
			||||||
      NODE_ENV: production
 | 
					      NODE_ENV: production
 | 
				
			||||||
      PAYLOAD_SECRET_FILE: /run/secrets/payload_secret
 | 
					      PAYLOAD_SECRET_FILE: /run/secrets/payload_secret
 | 
				
			||||||
 | 
					      PAYLOAD_CONFIG_PATH: /home/node/dist/payload.config.js
 | 
				
			||||||
 | 
					      PAYLOAD_PUBLIC_SERVER_URL: https://kios-admin.lumbung.space
 | 
				
			||||||
    configs:
 | 
					    configs:
 | 
				
			||||||
      - source: app_entrypoint
 | 
					      - source: app_entrypoint
 | 
				
			||||||
        target: /docker-entrypoint.sh
 | 
					        target: /docker-entrypoint.sh
 | 
				
			||||||
        mode: 0555
 | 
					        mode: 0555
 | 
				
			||||||
 | 
					    entrypoint: /docker-entrypoint.sh
 | 
				
			||||||
 | 
					    command: node dist/server.js
 | 
				
			||||||
    secrets:
 | 
					    secrets:
 | 
				
			||||||
      - payload_secret
 | 
					      - payload_secret
 | 
				
			||||||
    deploy:
 | 
					    deploy:
 | 
				
			||||||
@ -26,19 +31,19 @@ services:
 | 
				
			|||||||
        order: start-first
 | 
					        order: start-first
 | 
				
			||||||
      labels:
 | 
					      labels:
 | 
				
			||||||
        - "traefik.enable=true"
 | 
					        - "traefik.enable=true"
 | 
				
			||||||
        - "traefik.http.routers.coop-cloud-site.rule=Host(`kios-admin.lumbung.space`, `www.kios-admin.lumbung.space`)"
 | 
					        - "traefik.http.routers.kios-admin.rule=Host(`kios-admin.lumbung.space`, `www.kios-admin.lumbung.space`)"
 | 
				
			||||||
        - "traefik.http.routers.coop-cloud-site.entrypoints=web-secure"
 | 
					        - "traefik.http.routers.kios-admin.entrypoints=web-secure"
 | 
				
			||||||
        - "traefik.http.services.coop-cloud-site.loadbalancer.server.port=3000"
 | 
					        - "traefik.http.services.kios-admin.loadbalancer.server.port=3000"
 | 
				
			||||||
        - "traefik.http.routers.coop-cloud-site.tls.certresolver=production"
 | 
					        - "traefik.http.routers.kios-admin.tls.certresolver=production"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  db:
 | 
					  db:
 | 
				
			||||||
    image: mongo:6.0.3
 | 
					    image: mongo:6.0.3
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      - internal
 | 
				
			||||||
    command:
 | 
					    command:
 | 
				
			||||||
      - "--storageEngine=wiredTiger"
 | 
					      - "--storageEngine=wiredTiger"
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - data:/data/db
 | 
					      - data:/data/db
 | 
				
			||||||
    logging:
 | 
					 | 
				
			||||||
      driver: none
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
volumes:
 | 
					volumes:
 | 
				
			||||||
  app:
 | 
					  app:
 | 
				
			||||||
@ -46,6 +51,7 @@ volumes:
 | 
				
			|||||||
  data:
 | 
					  data:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
networks:
 | 
					networks:
 | 
				
			||||||
 | 
					  internal:
 | 
				
			||||||
  proxy:
 | 
					  proxy:
 | 
				
			||||||
    external: true
 | 
					    external: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								docker-compose-local.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								docker-compose-local.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					version: '3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					services:
 | 
				
			||||||
 | 
					  payload:
 | 
				
			||||||
 | 
					    image: node:21-bookworm
 | 
				
			||||||
 | 
					    ports:
 | 
				
			||||||
 | 
					      - '3000:3000'
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - .:/home/node/app
 | 
				
			||||||
 | 
					      - node_modules:/home/node/app/node_modules
 | 
				
			||||||
 | 
					    working_dir: /home/node/app/
 | 
				
			||||||
 | 
					    command: sh -c "yarn install && yarn dev"
 | 
				
			||||||
 | 
					    depends_on:
 | 
				
			||||||
 | 
					      - mongo
 | 
				
			||||||
 | 
					    env_file:
 | 
				
			||||||
 | 
					      - .env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mongo:
 | 
				
			||||||
 | 
					    image: mongo:latest
 | 
				
			||||||
 | 
					    ports:
 | 
				
			||||||
 | 
					      - '27017:27017'
 | 
				
			||||||
 | 
					    command:
 | 
				
			||||||
 | 
					      - --storageEngine=wiredTiger
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - data:/data/db
 | 
				
			||||||
 | 
					    logging:
 | 
				
			||||||
 | 
					      driver: none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					volumes:
 | 
				
			||||||
 | 
					  data:
 | 
				
			||||||
 | 
					  node_modules:
 | 
				
			||||||
@ -1,29 +1,5 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set -e
 | 
					export PAYLOAD_SECRET=$(cat /run/secrets/payload_secret)
 | 
				
			||||||
 | 
					 | 
				
			||||||
file_env() {
 | 
					 | 
				
			||||||
   local var="$1"
 | 
					 | 
				
			||||||
   local fileVar="${var}_FILE"
 | 
					 | 
				
			||||||
   local def="${2:-}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
 | 
					 | 
				
			||||||
      echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
 | 
					 | 
				
			||||||
      exit 1
 | 
					 | 
				
			||||||
   fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   local val="$def"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   if [ "${!var:-}" ]; then
 | 
					 | 
				
			||||||
      val="${!var}"
 | 
					 | 
				
			||||||
   elif [ "${!fileVar:-}" ]; then
 | 
					 | 
				
			||||||
      val="$(< "${!fileVar}")"
 | 
					 | 
				
			||||||
   fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   export "$var"="$val"
 | 
					 | 
				
			||||||
   unset "$fileVar"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
file_env "PAYLOAD_SECRET"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
node dist/server.js
 | 
					node dist/server.js
 | 
				
			||||||
 | 
				
			|||||||
@ -15,16 +15,17 @@
 | 
				
			|||||||
    "generate:graphQLSchema": "PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema"
 | 
					    "generate:graphQLSchema": "PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "payload": "^1.5.9",
 | 
					 | 
				
			||||||
    "dotenv": "^8.2.0",
 | 
					    "dotenv": "^8.2.0",
 | 
				
			||||||
    "express": "^4.17.1"
 | 
					    "express": "^4.17.1",
 | 
				
			||||||
 | 
					    "payload": "^1.5.9",
 | 
				
			||||||
 | 
					    "sharp": "^0.33.2"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@types/express": "^4.17.9",
 | 
					    "@types/express": "^4.17.9",
 | 
				
			||||||
 | 
					    "copyfiles": "^2.4.1",
 | 
				
			||||||
    "cross-env": "^7.0.3",
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
    "nodemon": "^2.0.6",
 | 
					    "nodemon": "^2.0.6",
 | 
				
			||||||
    "ts-node": "^9.1.1",
 | 
					    "ts-node": "^9.1.1",
 | 
				
			||||||
    "copyfiles": "^2.4.1",
 | 
					 | 
				
			||||||
    "typescript": "^4.8.4"
 | 
					    "typescript": "^4.8.4"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								src/collections/Couriers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/collections/Couriers.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					import { CollectionConfig } from 'payload/types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Couriers: CollectionConfig = {
 | 
				
			||||||
 | 
					  slug: 'couriers',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    useAsTitle: 'name',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  access: {
 | 
				
			||||||
 | 
					    read: () => true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'name',
 | 
				
			||||||
 | 
					      type: 'text',
 | 
				
			||||||
 | 
					      required: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'startingPoint',
 | 
				
			||||||
 | 
					      label: 'Traveling from',
 | 
				
			||||||
 | 
					      type: 'text', // TODO use geopicker here
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'destination',
 | 
				
			||||||
 | 
					      label: 'Traveling to',
 | 
				
			||||||
 | 
					      type: 'text' // TODO user geopicker here
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'departureDate',
 | 
				
			||||||
 | 
					      label: 'Departure date',
 | 
				
			||||||
 | 
					      type: 'date'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'arrivalDate',
 | 
				
			||||||
 | 
					      label: 'Arrival date',
 | 
				
			||||||
 | 
					      type: 'date'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'weightAllowance',
 | 
				
			||||||
 | 
					      label: 'Weight Allowance (KG)',
 | 
				
			||||||
 | 
					      type: 'number'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Couriers;
 | 
				
			||||||
							
								
								
									
										94
									
								
								src/collections/Dispatches.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/collections/Dispatches.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					import { CollectionConfig } from 'payload/types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Dispatches: CollectionConfig = {
 | 
				
			||||||
 | 
					  slug: 'dispatches',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    useAsTitle: 'dispatchesCode',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  access: {
 | 
				
			||||||
 | 
					    read: () => true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        name: 'dispatchesCode',
 | 
				
			||||||
 | 
					        type: 'text', 
 | 
				
			||||||
 | 
					        required: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'products', 
 | 
				
			||||||
 | 
					        type: 'relationship', 
 | 
				
			||||||
 | 
					        relationTo: 'products', 
 | 
				
			||||||
 | 
					        hasMany: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'startingPoint', 
 | 
				
			||||||
 | 
					        type: 'relationship', 
 | 
				
			||||||
 | 
					        relationTo: 'makers', 
 | 
				
			||||||
 | 
					        hasMany: false,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'endPoint', 
 | 
				
			||||||
 | 
					        type: 'relationship', 
 | 
				
			||||||
 | 
					        relationTo: 'retailers', 
 | 
				
			||||||
 | 
					        hasMany: false,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'typeOfTransportation',
 | 
				
			||||||
 | 
					        type: 'select',
 | 
				
			||||||
 | 
					        hasMany: true,
 | 
				
			||||||
 | 
					        options: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Air',
 | 
				
			||||||
 | 
					            value: 'air'
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Car',
 | 
				
			||||||
 | 
					            value: 'car'
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Train',
 | 
				
			||||||
 | 
					            value: 'train'
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Boat',
 | 
				
			||||||
 | 
					            value: 'boat'
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'courier', 
 | 
				
			||||||
 | 
					        type: 'relationship', 
 | 
				
			||||||
 | 
					        relationTo: 'couriers', 
 | 
				
			||||||
 | 
					        hasMany: false,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'timeSensitive', 
 | 
				
			||||||
 | 
					        type: 'checkbox', 
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'status', // required
 | 
				
			||||||
 | 
					        type: 'select', // required
 | 
				
			||||||
 | 
					        hasMany: true,
 | 
				
			||||||
 | 
					        // admin: {
 | 
				
			||||||
 | 
					        //   isClearable: true,
 | 
				
			||||||
 | 
					        //   isSortable: true, // use mouse to drag and drop different values, and sort them according to your choice
 | 
				
			||||||
 | 
					        // },
 | 
				
			||||||
 | 
					        options: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Route requested',
 | 
				
			||||||
 | 
					            value: 'routeRequested',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'In transit',
 | 
				
			||||||
 | 
					            value: 'inTransit',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            label: 'Completed',
 | 
				
			||||||
 | 
					            value: 'completed',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Dispatches;
 | 
				
			||||||
@ -1,17 +0,0 @@
 | 
				
			|||||||
import { CollectionConfig } from 'payload/types';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Example Collection - For reference only, this must be added to payload.config.ts to be used.
 | 
					 | 
				
			||||||
const Examples: CollectionConfig = {
 | 
					 | 
				
			||||||
  slug: 'examples',
 | 
					 | 
				
			||||||
  admin: {
 | 
					 | 
				
			||||||
    useAsTitle: 'someField',
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  fields: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      name: 'someField',
 | 
					 | 
				
			||||||
      type: 'text',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default Examples;
 | 
					 | 
				
			||||||
							
								
								
									
										29
									
								
								src/collections/Makers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/collections/Makers.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import { CollectionConfig } from 'payload/types';
 | 
				
			||||||
 | 
					import { geoPickerField } from "../customFields/geoPicker/field";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Makers: CollectionConfig = {
 | 
				
			||||||
 | 
					  slug: 'makers',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    useAsTitle: 'name',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  access: {
 | 
				
			||||||
 | 
					    read: () => true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        name: 'name', // required
 | 
				
			||||||
 | 
					        type: 'text', // required
 | 
				
			||||||
 | 
					        required: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      geoPickerField,
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'products', // required
 | 
				
			||||||
 | 
					        type: 'relationship', // required
 | 
				
			||||||
 | 
					        relationTo: 'products', // required
 | 
				
			||||||
 | 
					        hasMany: true,
 | 
				
			||||||
 | 
					        // TODO: make the name of the product visible in the dropdown
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Makers;
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/collections/Products.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/collections/Products.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					import { CollectionConfig } from 'payload/types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Products: CollectionConfig = {
 | 
				
			||||||
 | 
					  slug: 'products',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    useAsTitle: 'productTitle',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  access: {
 | 
				
			||||||
 | 
					    read: () => true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        name: 'productTitle', // required
 | 
				
			||||||
 | 
					        type: 'text', // required
 | 
				
			||||||
 | 
					        required: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Products;
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/collections/Retailers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/collections/Retailers.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					import { CollectionConfig } from 'payload/types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Retailers: CollectionConfig = {
 | 
				
			||||||
 | 
					  slug: 'retailers',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    useAsTitle: 'name',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  access: {
 | 
				
			||||||
 | 
					    read: () => true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        name: 'name', // required
 | 
				
			||||||
 | 
					        type: 'text', // required
 | 
				
			||||||
 | 
					        required: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'location',
 | 
				
			||||||
 | 
					        type: 'point',
 | 
				
			||||||
 | 
					        label: 'Location',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'products', // required
 | 
				
			||||||
 | 
					        type: 'relationship', // required
 | 
				
			||||||
 | 
					        relationTo: 'products', // required
 | 
				
			||||||
 | 
					        hasMany: true,
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Retailers;
 | 
				
			||||||
							
								
								
									
										63
									
								
								src/customFields/geoPicker/GeoPicker.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/customFields/geoPicker/GeoPicker.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					import * as React from 'react';
 | 
				
			||||||
 | 
					import { useField } from 'payload/components/forms';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const GeoPicker: React.FC<{ path: string }> = ({ path }) => {
 | 
				
			||||||
 | 
					  const { value, setValue } = useField<string>({ path });
 | 
				
			||||||
 | 
					  const [longitude, setLongitude] = React.useState(value[0]);
 | 
				
			||||||
 | 
					  const [latitude, setLatitude] = React.useState(value[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleCityEnter = async (e) => {
 | 
				
			||||||
 | 
					    if (e.key === 'Enter') {
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        const response = await fetch(
 | 
				
			||||||
 | 
					          `https://nominatim.openstreetmap.org/search?format=json&q=${e.target.value}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const data = await response.json();
 | 
				
			||||||
 | 
					        if (data && data.length > 0) {
 | 
				
			||||||
 | 
					          const { lat, lon } = data[0];
 | 
				
			||||||
 | 
					          setLatitude(lat);
 | 
				
			||||||
 | 
					          setLongitude(lon);
 | 
				
			||||||
 | 
					          setValue([lon, lat]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } catch (error) {
 | 
				
			||||||
 | 
					        console.error('Error fetching geolocation:', error);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleLatitudeChange = (e) => {
 | 
				
			||||||
 | 
					    setLatitude(e.target.value);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleLongitudeChange = (e) => {
 | 
				
			||||||
 | 
					    setLongitude(e.target.value);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <div className='field-type text'>
 | 
				
			||||||
 | 
					        <label className='field-label'>
 | 
				
			||||||
 | 
					          City
 | 
				
			||||||
 | 
					        </label>
 | 
				
			||||||
 | 
					        <input
 | 
				
			||||||
 | 
					          type="text"
 | 
				
			||||||
 | 
					          className='field-name'
 | 
				
			||||||
 | 
					          onKeyDown={handleCityEnter}
 | 
				
			||||||
 | 
					          placeholder="Enter city to get coordinates"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div className="field-type point">
 | 
				
			||||||
 | 
					        <ul className='point__wrap'>
 | 
				
			||||||
 | 
					          <li>
 | 
				
			||||||
 | 
					            <label className='field-label'>Location - Longitude</label>
 | 
				
			||||||
 | 
					            <input id="field-longitude-location" type="number" name="location.longitude" value={longitude} onChange={handleLongitudeChange}></input>
 | 
				
			||||||
 | 
					          </li>
 | 
				
			||||||
 | 
					          <li>
 | 
				
			||||||
 | 
					            <label className='field-label'>Location - Latitude</label>
 | 
				
			||||||
 | 
					            <input id="field-latitude-latitude" type="number" name="location.latitude" value={latitude} onChange={handleLatitudeChange}></input>
 | 
				
			||||||
 | 
					          </li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/customFields/geoPicker/field.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/customFields/geoPicker/field.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import { PointField } from 'payload/types';
 | 
				
			||||||
 | 
					import { GeoPicker } from './GeoPicker';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const geoPickerField: PointField = {
 | 
				
			||||||
 | 
					  name: 'Location',
 | 
				
			||||||
 | 
					  type: 'point',
 | 
				
			||||||
 | 
					  admin: {
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					      Field: GeoPicker,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,16 +2,25 @@ import { buildConfig } from 'payload/config';
 | 
				
			|||||||
import path from 'path';
 | 
					import path from 'path';
 | 
				
			||||||
// import Examples from './collections/Examples';
 | 
					// import Examples from './collections/Examples';
 | 
				
			||||||
import Users from './collections/Users';
 | 
					import Users from './collections/Users';
 | 
				
			||||||
 | 
					import Couriers from './collections/Couriers';
 | 
				
			||||||
 | 
					import Dispatches from './collections/Dispatches';
 | 
				
			||||||
 | 
					import Makers from './collections/Makers';
 | 
				
			||||||
 | 
					import Products from './collections/Products';
 | 
				
			||||||
 | 
					import Retailers from './collections/Retailers';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default buildConfig({
 | 
					export default buildConfig({
 | 
				
			||||||
  serverURL: 'http://localhost:3000',
 | 
					  serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
 | 
				
			||||||
  admin: {
 | 
					  admin: {
 | 
				
			||||||
    user: Users.slug,
 | 
					    user: Users.slug,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  collections: [
 | 
					  collections: [
 | 
				
			||||||
    Users,
 | 
					    Users,
 | 
				
			||||||
    // Add Collections here
 | 
					    Couriers,
 | 
				
			||||||
    // Examples,
 | 
					    Dispatches,
 | 
				
			||||||
 | 
					    Makers,
 | 
				
			||||||
 | 
					    Products,
 | 
				
			||||||
 | 
					    Retailers,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  typescript: {
 | 
					  typescript: {
 | 
				
			||||||
    outputFile: path.resolve(__dirname, 'payload-types.ts'),
 | 
					    outputFile: path.resolve(__dirname, 'payload-types.ts'),
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ payload.init({
 | 
				
			|||||||
  express: app,
 | 
					  express: app,
 | 
				
			||||||
  onInit: () => {
 | 
					  onInit: () => {
 | 
				
			||||||
    payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
 | 
					    payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
 | 
				
			||||||
  },
 | 
					  }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add your own express routes here
 | 
					// Add your own express routes here
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user