0% found this document useful (0 votes)
19 views25 pages

Building PlacePal

The document provides a step-by-step guide to building PlacePal, a location-based service request and real-time tracking app for Nigeria's POS ecosystem, using Visual Studio Code. It covers setting up the development environment, creating the front-end with React Native, and building the back-end with Node.js and Express, including code snippets and instructions for integrating necessary APIs. The guide is designed for beginners with basic computer skills and aims to minimize costs by using free and open-source tools.

Uploaded by

fortuneburbkatti
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views25 pages

Building PlacePal

The document provides a step-by-step guide to building PlacePal, a location-based service request and real-time tracking app for Nigeria's POS ecosystem, using Visual Studio Code. It covers setting up the development environment, creating the front-end with React Native, and building the back-end with Node.js and Express, including code snippets and instructions for integrating necessary APIs. The guide is designed for beginners with basic computer skills and aims to minimize costs by using free and open-source tools.

Uploaded by

fortuneburbkatti
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

Building **PlacePal**, your POS agent registration, verification, location-

based service request, and real-time tracking app, using Visual Studio Code
(VS Code) is a cost-effective approach to avoid hiring developers. Since
you’re aiming to develop both the front-end and back-end yourself, I’ll guide
you step-by-step through the process, tailoring it to a beginner-friendly level
while ensuring the app is functional for Nigeria’s POS ecosystem. This guide
assumes you have basic computer skills but little to no coding experience.
We’ll use **React Native** for the front-end (mobile app for iOS/Android),
**Node.js with Express** for the back-end, **MongoDB** for the database,
and **Socket.io** for real-time tracking, as these are cost-effective and
widely supported tools.

The steps below include setting up your development environment, writing


the front-end and back-end code, integrating APIs (e.g., for KYC and
payments), and testing the app. I’ll provide simplified code snippets,
explanations, and commands to run in VS Code’s terminal. This approach
minimizes costs by using free/open-source tools and leveraging Nigeria-
specific APIs like Flutterwave and YouVerify.

---

### **Step-by-Step Guide to Build PlacePal in Visual Studio Code**

#### **Step 1: Set Up Your Development Environment**

1. **Install Visual Studio Code**:

- Download and install VS Code from


[code.visualstudio.com](https://code.visualstudio.com) (free).

- Open VS Code and install the following extensions (via the Extensions
panel, Ctrl+Shift+X):

- **ESLint**: For JavaScript code quality.

- **Prettier**: For code formatting.

- **React Native Tools**: For React Native debugging.


- **MongoDB for VS Code**: For database management.

2. **Install Node.js**:

- Download and install Node.js (LTS version) from


[nodejs.org](https://nodejs.org) (includes npm, the package manager).

- Verify installation in VS Code’s terminal (Ctrl+` to open):

```bash

node -v

npm -v

```

Expect versions like `v20.x.x` and `v10.x.x`.

3. **Install MongoDB**:

- Download MongoDB Community Server from


[mongodb.com](https://www.mongodb.com/try/download/community) or use
**MongoDB Atlas** (free cloud database).

- For local setup: Install and run MongoDB as a service.

- For Atlas: Sign up, create a free cluster, and note the connection string
(e.g.,
`mongodb+srv://<username>:<password>@cluster0.mongodb.net/placepal
`).

- Verify MongoDB is running:

```bash

mongod --version

```

4. **Install Expo CLI** (for React Native):

- In VS Code’s terminal:

```bash
npm install -g expo-cli

```

- Verify:

```bash

expo --version

```

5. **Set Up Android/iOS Emulator**:

- For Android:

- Install **Android Studio** from


[developer.android.com](https://developer.android.com/studio).

- Set up an Android emulator (e.g., Pixel 6) via Android Studio’s Device


Manager.

- For iOS (Mac only):

- Install **Xcode** from the Mac App Store and set up an iOS simulator.

- Alternatively, use Expo Go (a mobile app) to test on your physical phone.

6. **Create Project Folder**:

- In VS Code, click “File” > “Open Folder” and create a new folder named
`PlacePal`.

- Open the terminal in VS Code (Ctrl+`) and navigate to the folder:

```bash

cd ~/path/to/PlacePal

```

---

#### **Step 2: Build the Front-End (React Native)**


We’ll create a mobile app with a registration form, map-based dashboard,
and service request modal.

1. **Initialize React Native Project**:

- In the VS Code terminal:

```bash

npx create-expo-app placepal-frontend

cd placepal-frontend

```

- Install dependencies for maps, API calls, and notifications:

```bash

npm install react-native-maps axios react-native-push-notification @react-


navigation/native @react-navigation/stack

```

2. **Create Front-End Structure**:

- In the `placepal-frontend` folder, create the following files in VS Code:

- `App.js`: Main app entry point.

- `screens/RegisterScreen.js`: Agent registration form.

- `screens/DashboardScreen.js`: Customer dashboard with map.

- `screens/RequestScreen.js`: Service request modal.

3. **Code the Front-End**:

- **App.js** (Navigation setup):

```javascript

import { NavigationContainer } from '@react-navigation/native';

import { createStackNavigator } from '@react-navigation/stack';


import RegisterScreen from './screens/RegisterScreen';

import DashboardScreen from './screens/DashboardScreen';

import RequestScreen from './screens/RequestScreen';

const Stack = createStackNavigator();

export default function App() {

return (

<NavigationContainer>

<Stack.Navigator>

<Stack.Screen name="Register" component={RegisterScreen}


options={{ title: 'PlacePal - Agent Register' }} />

<Stack.Screen name="Dashboard" component={DashboardScreen}


options={{ title: 'PlacePal - Find Agents' }} />

<Stack.Screen name="Request" component={RequestScreen}


options={{ title: 'PlacePal - Request Service' }} />

</Stack.Navigator>

</NavigationContainer>

);

```

- **screens/RegisterScreen.js** (Agent registration form):

```javascript

import React, { useState } from 'react';

import { View, Text, TextInput, Button, StyleSheet, Alert } from 'react-


native';

import axios from 'axios';


export default function RegisterScreen({ navigation }) {

const [name, setName] = useState('');

const [phone, setPhone] = useState('');

const [bvn, setBvn] = useState('');

const [address, setAddress] = useState('');

const handleRegister = async () => {

try {

const response = await axios.post('http://localhost:3000/api/register',


{ name, phone, bvn, address });

Alert.alert('Success', response.data.message);

navigation.navigate('Dashboard');

} catch (error) {

Alert.alert('Error', error.response?.data?.error || 'Registration failed');

};

return (

<View style={styles.container}>

<Text style={styles.title}>Agent Registration</Text>

<TextInput style={styles.input} placeholder="Full Name"


value={name} onChangeText={setName} />

<TextInput style={styles.input} placeholder="Phone Number"


value={phone} onChangeText={setPhone} keyboardType="phone-pad" />

<TextInput style={styles.input} placeholder="BVN" value={bvn}


onChangeText={setBvn} keyboardType="numeric" />
<TextInput style={styles.input} placeholder="Business Address"
value={address} onChangeText={setAddress} />

<Button title="Register" onPress={handleRegister} color="#1a73e8"


/>

<Button title="Go to Dashboard" onPress={() =>


navigation.navigate('Dashboard')} />

</View>

);

const styles = StyleSheet.create({

container: { flex: 1, padding: 20, backgroundColor: '#f4f4f4' },

title: { fontSize: 24, fontWeight: 'bold', color: '#1a73e8', marginBottom:


20 },

input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom:


10, borderRadius: 5 },

});

```

- **screens/DashboardScreen.js** (Map-based dashboard):

```javascript

import React, { useEffect, useState } from 'react';

import { View, Text, Button, StyleSheet } from 'react-native';

import MapView, { Marker } from 'react-native-maps';

import axios from 'axios';

export default function DashboardScreen({ navigation }) {

const [agents, setAgents] = useState([]);


useEffect(() => {

// Fetch nearby agents (mock for now)

const mockAgents = [

{ id: 1, name: 'Agent John', latitude: 6.5244, longitude: 3.3792,


services: ['Withdrawal', 'Transfer'] },

{ id: 2, name: 'Agent Sarah', latitude: 6.5344, longitude: 3.3892,


services: ['Withdrawal', 'Bill Payment'] },

];

setAgents(mockAgents);

// Replace with real API call later

// axios.get('http://localhost:3000/api/agents/nearby?
lat=6.5244&lng=3.3792').then(res => setAgents(res.data));

}, []);

return (

<View style={styles.container}>

<Text style={styles.title}>Find Nearby POS Agents</Text>

<MapView

style={styles.map}

initialRegion={{

latitude: 6.5244, // Lagos

longitude: 3.3792,

latitudeDelta: 0.0922,

longitudeDelta: 0.0421,

}}

>

{agents.map(agent => (
<Marker

key={agent.id}

coordinate={{ latitude: agent.latitude, longitude:


agent.longitude }}

title={agent.name}

description={`Services: ${agent.services.join(', ')}`}

onPress={() => navigation.navigate('Request', { agentId:


agent.id })}

/>

))}

</MapView>

<Button title="Request Service" onPress={() =>


navigation.navigate('Request')} color="#1a73e8" />

</View>

);

const styles = StyleSheet.create({

container: { flex: 1, padding: 20, backgroundColor: '#f4f4f4' },

title: { fontSize: 24, fontWeight: 'bold', color: '#1a73e8', marginBottom:


20 },

map: { flex: 1, borderRadius: 5 },

});

```

- **screens/RequestScreen.js** (Service request modal):

```javascript

import React, { useState } from 'react';


import { View, Text, TextInput, Button, StyleSheet, Alert } from 'react-
native';

import axios from 'axios';

export default function RequestScreen({ route }) {

const { agentId } = route.params || {};

const [serviceType, setServiceType] = useState('withdrawal');

const [amount, setAmount] = useState('');

const handleRequest = async () => {

try {

const response = await axios.post('http://localhost:3000/api/request',


{ agentId, serviceType, amount });

Alert.alert('Success', response.data.message);

} catch (error) {

Alert.alert('Error', error.response?.data?.error || 'Request failed');

};

return (

<View style={styles.container}>

<Text style={styles.title}>Request Service</Text>

<Text style={styles.label}>Service Type</Text>

<TextInput

style={styles.input}

value={serviceType}

onChangeText={setServiceType}
placeholder="e.g., withdrawal, transfer, bill"

/>

<Text style={styles.label}>Amount (₦)</Text>

<TextInput

style={styles.input}

value={amount}

onChangeText={setAmount}

keyboardType="numeric"

placeholder="Enter amount"

/>

<Button title="Submit Request" onPress={handleRequest}


color="#1a73e8" />

</View>

);

const styles = StyleSheet.create({

container: { flex: 1, padding: 20, backgroundColor: '#f4f4f4' },

title: { fontSize: 24, fontWeight: 'bold', color: '#1a73e8', marginBottom:


20 },

label: { fontSize: 16, marginBottom: 5 },

input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom:


10, borderRadius: 5 },

});

```

4. **Test the Front-End**:

- In the `placepal-frontend` folder, run:


```bash

npx expo start

```

- Scan the QR code with the **Expo Go** app on your phone or open the
Android/iOS emulator.

- You’ll see a basic app with:

- A registration screen (mock submission).

- A dashboard with a map showing two mock agents in Lagos.

- A request screen for selecting services and amounts.

---

#### **Step 3: Build the Back-End (Node.js + Express)**

The back-end handles agent registration, verification, nearby agent


searches, and service requests.

1. **Initialize Node.js Project**:

- In the `PlacePal` folder, create a new folder for the back-end:

```bash

mkdir placepal-backend

cd placepal-backend

npm init -y

```

- Install dependencies:

```bash

npm install express mongoose socket.io node-geocoder

```
2. **Create Back-End Code**:

- In the `placepal-backend` folder, create `server.js`:

```javascript

const express = require('express');

const mongoose = require('mongoose');

const socketIo = require('socket.io');

const http = require('http');

const cors = require('cors');

const NodeGeocoder = require('node-geocoder');

const app = express();

const server = http.createServer(app);

const io = socketIo(server, { cors: { origin: '*' } });

app.use(cors());

app.use(express.json());

// Connect to MongoDB

mongoose.connect('mongodb://localhost/placepal', { useNewUrlParser:
true, useUnifiedTopology: true })

.then(() => console.log('MongoDB connected'))

.catch(err => console.error(err));

// Geocoder for address-to-coordinates

const geocoder = NodeGeocoder({ provider: 'openstreetmap' });


// Agent Schema

const agentSchema = new mongoose.Schema({

name: String,

phone: String,

bvn: String,

address: String,

location: { type: { type: String, enum: ['Point'] }, coordinates:


[Number] },

verified: Boolean,

});

agentSchema.index({ location: '2dsphere' });

const Agent = mongoose.model('Agent', agentSchema);

// Register Agent

app.post('/api/register', async (req, res) => {

const { name, phone, bvn, address } = req.body;

try {

// Mock KYC verification (replace with YouVerify/Smile ID API)

if (bvn.length !== 11) throw new Error('Invalid BVN');

const geoData = await geocoder.geocode(address);

if (!geoData[0]) throw new Error('Invalid address');

const agent = new Agent({

name,

phone,

bvn,

address,
location: { type: 'Point', coordinates: [geoData[0].longitude,
geoData[0].latitude] },

verified: true,

});

await agent.save();

res.json({ message: 'Agent registered' });

} catch (error) {

res.status(400).json({ error: error.message });

});

// Find Nearby Agents

app.get('/api/agents/nearby', async (req, res) => {

const { lat, lng } = req.query;

try {

const agents = await Agent.find({

location: {

$near: { $geometry: { type: 'Point', coordinates: [parseFloat(lng),


parseFloat(lat)] }, $maxDistance: 5000 },

},

});

res.json(agents);

} catch (error) {

res.status(400).json({ error: 'Error fetching agents' });

});
// Service Request

app.post('/api/request', async (req, res) => {

const { agentId, serviceType, amount } = req.body;

try {

// Mock payment (replace with Flutterwave/Paystack API)

if (!agentId || !serviceType || !amount) throw new Error('Invalid


request');

io.emit('newRequest', { agentId, serviceType, amount });

res.json({ message: 'Request submitted' });

} catch (error) {

res.status(400).json({ error: error.message });

});

// Real-Time Tracking

io.on('connection', (socket) => {

console.log('Client connected');

socket.on('updateLocation', async ({ agentId, lat, lng }) => {

await Agent.updateOne(

{ _id: agentId },

{ location: { type: 'Point', coordinates: [parseFloat(lng),


parseFloat(lat)] } }

);

io.emit('locationUpdate', { agentId, lat, lng });

});

});
server.listen(3000, () => console.log('PlacePal server running on
http://localhost:3000'));

```

3. **Test the Back-End**:

- Ensure MongoDB is running (locally or via Atlas).

- In the `placepal-backend` folder, run:

```bash

node server.js

```

- You should see “MongoDB connected” and “PlacePal server running on


http://localhost:3000”.

4. **Test API Endpoints** (using Postman or VS Code REST Client):

- **Register Agent**:

```http

POST http://localhost:3000/api/register

Content-Type: application/json

"name": "John Doe",

"phone": "08012345678",

"bvn": "12345678901",

"address": "Ikeja, Lagos, Nigeria"

```

- **Get Nearby Agents**:

```http
GET http://localhost:3000/api/agents/nearby?lat=6.5244&lng=3.3792

```

- **Submit Request**:

```http

POST http://localhost:3000/api/request

Content-Type: application/json

"agentId": "replace_with_mongodb_id",

"serviceType": "withdrawal",

"amount": 5000

```

---

#### **Step 4: Integrate Real-Time Tracking**

1. **Add Socket.io to Front-End**:

- Install Socket.io client:

```bash

cd placepal-frontend

npm install socket.io-client

```

- Update `DashboardScreen.js` to listen for location updates:

```javascript

import io from 'socket.io-client';

// Inside DashboardScreen component

useEffect(() => {
const socket = io('http://localhost:3000');

socket.on('locationUpdate', ({ agentId, lat, lng }) => {

setAgents(prev =>

prev.map(agent =>

agent.id === agentId ? { ...agent, latitude: lat, longitude: lng } :


agent

);

});

return () => socket.disconnect();

}, []);

```

2. **Test Real-Time Tracking**:

- Simulate location updates by sending a WebSocket message (e.g., via a


test script or Postman WebSocket):

```javascript

"agentId": "replace_with_mongodb_id",

"lat": 6.5250,

"lng": 3.3800

```

- The map should update marker positions (requires real agent IDs from
MongoDB).

---
#### **Step 5: Integrate APIs**

1. **KYC Verification (YouVerify/Smile ID)**:

- Sign up for YouVerify or Smile ID (expect $0.1–$1 per verification).

- Update `server.js` to verify BVN:

```javascript

// Install: npm install axios

const axios = require('axios');

app.post('/api/register', async (req, res) => {

const { name, phone, bvn, address } = req.body;

try {

const kycResponse = await


axios.post('https://api.youverify.co/v2/verifications/bvn', {

id: bvn,

apiKey: 'YOUR_YOUVERIFY_API_KEY',

});

if (!kycResponse.data.success) throw new Error('Invalid BVN');

// Continue with geocoder and agent saving...

} catch (error) {

res.status(400).json({ error: error.message });

});

```

2. **Payments (Flutterwave/Paystack)**:

- Sign up for Flutterwave or Paystack (sandbox mode for testing).

- Update `server.js` for payments:

```javascript
const Flutterwave = require('flutterwave-node-v3');

const flw = new Flutterwave('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY');

app.post('/api/request', async (req, res) => {

const { agentId, serviceType, amount } = req.body;

try {

const payment = await flw.Charge.card({

card_number: 'TEST_CARD_NUMBER',

cvv: '123',

expiry_month: '09',

expiry_year: '25',

amount,

email: '[email protected]',

tx_ref: `placepal_${Date.now()}`,

});

if (payment.status !== 'success') throw new Error('Payment failed');

io.emit('newRequest', { agentId, serviceType, amount });

res.json({ message: 'Request submitted' });

} catch (error) {

res.status(400).json({ error: error.message });

});

```

3. **Geolocation**:

- The `node-geocoder` package is already included in `server.js` for


address-to-coordinates conversion.

- Replace with Google Maps API if needed (requires API key, ~$5/month).
---

#### **Step 6: Test the Full App**

1. **Run Back-End**:

- In the `placepal-backend` folder:

```bash

node server.js

```

2. **Run Front-End**:

- In the `placepal-frontend` folder:

```bash

npx expo start

```

- Test on your phone (via Expo Go) or emulator.

3. **Test Features**:

- Register an agent (submit form, check MongoDB for stored data).

- View nearby agents on the map (mock data initially).

- Submit a service request and verify the alert.

- Simulate location updates via WebSocket (requires manual testing until


real devices are used).

---

#### **Step 7: Deploy the App**

1. **Back-End Deployment (Heroku)**:

- Sign up for Heroku (free tier available).


- Install Heroku CLI:

```bash

npm install -g heroku

```

- Deploy:

```bash

cd placepal-backend

heroku create placepal-backend

git init

git add .

git commit -m "Initial commit"

git push heroku main

```

- Set up MongoDB Atlas and update `server.js` with the Atlas connection
string.

2. **Front-End Deployment (Expo)**:

- Build the app for production:

```bash

cd placepal-frontend

npx expo export

```

- Publish to Google Play/App Store (requires developer accounts: $25 one-


time for Google, $99/year for Apple).

- Alternatively, share the app via Expo’s QR code for testing.

---
#### **Cost Breakdown (DIY Approach)**

- **Software**: Free (VS Code, Node.js, MongoDB, Expo).

- **APIs**:

- YouVerify: ~$0.1–$1 per KYC check (budget $100 for initial 100–1,000
verifications).

- Flutterwave/Paystack: Free sandbox, 1–2% transaction fees in production.

- Google Maps API: ~$5/month (optional, Node-Geocoder is free).

- **Hosting**:

- Heroku: Free tier or $7–$50/month for scaling.

- MongoDB Atlas: Free tier (512MB) or $9/month for 2GB.

- **Total Initial Cost**: $100–$200 (excluding Play Store/App Store fees).

---

#### **Learning Resources**

Since you’re building this yourself, here are beginner-friendly resources:

- **React Native**: [Expo Docs](https://docs.expo.dev), [React Native


Tutorial](https://www.youtube.com/watch?v=0-S5a0eKiOc).

- **Node.js/Express**: [freeCodeCamp Node.js


Course](https://www.youtube.com/watch?v=TNV0_7QRDwY).

- **MongoDB**: [MongoDB University](https://university.mongodb.com).

- **APIs**: Flutterwave/Paystack developer docs, YouVerify API guides.

---

#### **Tips for Success**


- **Start Small**: Focus on the MVP (registration, map, requests) and test in
a small area (e.g., Port Harcourt, based on your interest in the region).

- **Learn Incrementally**: Spend 1–2 hours daily on tutorials. Start with


React Native, then Node.js, and finally APIs.

- **Test Locally**: Use mock data initially to save on API costs.

- **Leverage Community**: Join Nigerian tech communities (e.g., Andela


Learning Community, Devcenter) for free mentorship.

- **Regulatory Compliance**: Consult a fintech lawyer (e.g., via Upwork,


~$50/hour) to ensure CBN compliance for KYC and transactions.

---

#### **Next Steps**

1. **Set Up Environment**: Follow Step 1 to install VS Code, Node.js,


MongoDB, and Expo.

2. **Build Front-End**: Create and test the React Native app (Steps 2–3).

3. **Build Back-End**: Set up and test the Node.js server (Step 4).

4. **Integrate APIs**: Add KYC and payment APIs (Step 5).

5. **Test and Iterate**: Run the app locally, fix bugs, and add features like
offline mode.

6. **Deploy**: Launch on Heroku and Expo (Step 7).

If you hit any roadblocks (e.g., errors in VS Code, API setup issues), share the
specific problem, and I’ll provide tailored code or commands to fix it. I can
also break down any step further or provide additional resources for learning.
Want to start with a specific part (e.g., front-end or back-end) or need help
with a particular feature? Let me know!

You might also like