# Complete source code for CRM sample
# public/index.html
<html>
<head>
<title>Acme Inc CRM</title>
<!-- #region header -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- #endregion header -->
</head>
<body>
<div class="container my-4">
<h1>Acme Inc CRM</h1>
<p>Welcome to our customer database</p>
<div id="app" class="my-4">
<div v-if="showCustomerList">
<h2>Customer list</h2>
<table class="table">
<thead>
<th>Organisation number</th>
<th>Name</th>
<th>Phone</th>
<th>Address</th>
</thead>
<tbody>
<tr v-for="company in companies" :key="company.organisationNumber">
<td>{{company.organisationNumber}}</td>
<td>{{company.name}}</td>
<td>{{company.phoneNumber}}</td>
<td>{{company.address}}</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" @click="showCustomerDialog = true; showCustomerList = false">Add new customer</button>
<div v-if="added" class="my-2 alert alert-success" role="alert">
Customer added to CRM.
</div>
</div>
<div v-show="showCustomerDialog">
<h2>Add new customer</h2>
<form @submit.prevent="search">
<input class="form-control" type="text" v-model="name" placeholder="Enter company name"/>
<br />
<input class="btn btn-success" type="submit" value="Search" />
<input @click="showCustomerDialog = false; showCustomerList = true;" class="btn btn-danger" type="reset" value="Cancel" />
</form>
<span v-if="numberOfHits != null && numberOfHits >= 0">Search results: {{numberOfHits}}</span>
<!-- #region searchResultList -->
<ul class="list-group list-group-flush">
<li class="list-group-item" v-for="res in searchResults" :key="res.companyId">
<button class="btn btn-primary" @click="add(res)">Add to CRM</button>
{{res.name}} ({{res.organisationNumber}})
</li>
</ul>
<!-- #endregion searchResultList -->
</div>
</div>
<script src="main.js"></script>
</div>
</body>
</html>
# public/main.js
var app = new Vue({
el: '#app',
data() {
return {
added: false,
showCustomerList: true,
showCustomerDialog: false,
name: '',
searchResults: [],
numberOfHits: null,
companies: JSON.parse(localStorage.getItem('companies')) || []
}
},
methods: {
add(company) {
this.companies.push({
name: company.name,
organisationNumber: company.organisationNumber,
phone: company.phoneNumbers && company.phoneNumbers.telephoneNumber,
address: company.postalAddress && Object.keys(company.postalAddress).map(k => company.postalAddress[k]).filter(v => v != null).join(', ')
})
// Synchronize localStorage
localStorage.setItem('companies', JSON.stringify(this.companies))
// Hide search and reset model
this.added = true;
this.showCustomerDialog = false;
this.showCustomerList = true;
this.searchResults = []
this.numberOfHits = null;
this.name = ''
},
//#region search
search() {
fetch(`/search?name=${this.name}`)
.then(r => {
if (r.ok) {
return r.json()
} else {
return {searchResults: [], numberOfHits: 0}
}
})
.then(data => {
this.searchResults = data.companies
this.numberOfHits = data.numberOfHits
})
}
//#endregion search
}
})
# routes/search.js
const express = require('express');
const router = express.Router();
const axios = require('axios');
const API_TOKEN = process.env.API_TOKEN // Your API token
const API_ENDPOINT = 'https://api.proff.no/api/companies/eniropro/NO'
const httpClient = axios.create({
timeout: 1000,
baseURL: API_ENDPOINT,
headers: {
'Authorization': `Token ${API_TOKEN}`,
'api-version': '1.1'
},
responseType: 'json'
});
/* GET home page. */
router.get('/', async function(req, res, next) {
try {
const proffApiResponse = await httpClient.get(`?name=${encodeURIComponent(req.query.name)}`);
res.json(proffApiResponse.data);
} catch (error) {
next(error)
}
});
module.exports = router;
# app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//#region searchRoute
var searchRouter = require('./routes/search');
app.use('/search', searchRouter);
//#endregion searchRoute
module.exports = app;