Refactor of api calls, removed db calls and unessary views
This commit is contained in:
parent
00aeae2b04
commit
e754178d8d
303
index.js
303
index.js
@ -12,6 +12,7 @@ const PropertyModel = require('./models/property');
|
|||||||
const PropertyContactModel = require('./models/propertyContact');
|
const PropertyContactModel = require('./models/propertyContact');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
|
|
||||||
@ -25,18 +26,18 @@ const opportunity = require('./models/opportunity');
|
|||||||
|
|
||||||
|
|
||||||
mongoose.connect('mongodb://127.0.0.1:27017/test')
|
mongoose.connect('mongodb://127.0.0.1:27017/test')
|
||||||
.then(()=>{
|
.then(() => {
|
||||||
console.log("Connection Open")
|
console.log("Connection Open")
|
||||||
})
|
})
|
||||||
.catch(err =>{
|
.catch(err => {
|
||||||
console.log("ERROR")
|
console.log("ERROR")
|
||||||
console.log(err)
|
console.log(err)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const db = mongoose.connection;
|
const db = mongoose.connection;
|
||||||
db.on("error", console.error.bind(console, "connection error"));
|
db.on("error", console.error.bind(console, "connection error"));
|
||||||
db.once("open", ()=>{
|
db.once("open", () => {
|
||||||
console.log("Database connected");
|
console.log("Database connected");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -52,15 +53,15 @@ sgMail.setApiKey(process.env.SENDGRID_API_KEY);
|
|||||||
app.use(express.static(path.join(__dirname, 'public')))
|
app.use(express.static(path.join(__dirname, 'public')))
|
||||||
|
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
app.set('views', path.join(__dirname,'/views'));
|
app.set('views', path.join(__dirname, '/views'));
|
||||||
|
|
||||||
|
|
||||||
//index route
|
//index route
|
||||||
app.get('/', (req, res)=>{
|
app.get('/', (req, res) => {
|
||||||
res.render('home')
|
res.render('home')
|
||||||
})
|
})
|
||||||
//POST Authorize route to gain access
|
//POST Authorize route to gain access
|
||||||
app.post('/authorize', async (req, res)=>{
|
app.post('/authorize', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_API_SECRET_KEY } = process.env;
|
const { ASPIRE_API_CLIENT_ID, ASPIRE_API_SECRET_KEY } = process.env;
|
||||||
const tokenUrl = 'https://cloud-api.youraspire.com/Authorization';
|
const tokenUrl = 'https://cloud-api.youraspire.com/Authorization';
|
||||||
@ -77,228 +78,104 @@ app.post('/authorize', async (req, res)=>{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//WORK TICKET VISIT ROUTES
|
/**** MESSAGING FEATURE ROUTES ****/
|
||||||
// api GET WORK TICKET VISITS
|
app.get('/data-for-messages', async (req, res) => {
|
||||||
app.get('/api/workticketvisits', async (req, res) => {
|
|
||||||
try {
|
try {
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_TOKEN, ASPIRE_REFRESH_TOKEN } = process.env;
|
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/WorkTicketVisits?%24select=WorkTicketVisitID%2CWorkTicketID%2CScheduledDate&%24filter=ScheduledDate%20gt%202024-01-29`;
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN }`,
|
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
|
||||||
const workticketvisits = response.data;
|
|
||||||
//save to database before going to client
|
|
||||||
// therefore logic to have databse filter logic beofre going to client
|
|
||||||
|
|
||||||
|
|
||||||
res.render('./workticketvisits', { workticketvisits });
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//API - GET - WORK TICKETS
|
|
||||||
app.get('/api/worktickets', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_TOKEN, ASPIRE_REFRESH_TOKEN } = process.env;
|
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/WorkTickets`;
|
|
||||||
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN }`,
|
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
|
||||||
const workTickets = response.data;
|
|
||||||
// await tickets.save();
|
|
||||||
res.json({ workTickets });
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// GET ALL OPPORTUNITIES
|
|
||||||
app.get('/api/opportunities', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_TOKEN, ASPIRE_REFRESH_TOKEN } = process.env;
|
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/opportunities`;
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
|
||||||
const opportunities = response.data;
|
|
||||||
// await tickets.save();
|
|
||||||
res.json({ opportunities });
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//INDEX - GET ALL customer contacts
|
|
||||||
app.get('api/contacts', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_API_SECRET_KEY, ASPIRE_TOKEN, ASPIRE_REFRESH_TOKEN } = process.env;
|
|
||||||
|
|
||||||
// Implement logic to fetch appointment data using Axios and API keys
|
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/Contacts?$filter=ContactTypeName eq 'Customer' and LastName ne 'Employee'&$select=FirstName,LastName,Email,CompanyName`; // Replace with the actual API endpoint
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
|
||||||
|
|
||||||
const contacts = response.data; // Assuming the response directly provides contacts
|
|
||||||
|
|
||||||
|
|
||||||
res.render('contacts', { contacts });
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//INDEX - GET ALL PROPERTIES
|
|
||||||
app.get('/api/properties', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_API_SECRET_KEY, ASPIRE_TOKEN } = process.env;
|
const { ASPIRE_API_CLIENT_ID, ASPIRE_API_SECRET_KEY, ASPIRE_TOKEN } = process.env;
|
||||||
|
//Specific api routes with details needed
|
||||||
// Implement logic to fetch appointment data using Axios and API keys
|
const apiPropertyUrl = `https://cloud-api.youraspire.com/Properties?%24select=PropertyID%2CSequenceNumber%2CPropertyName%2CPropertyAddressLine1%2CPropertyAddressLine2%2CPropertyAddressCity%2CPropertyAddressStateProvinceCode%2CPropertyAddressZipCode%2CBranchName`;
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/properties`; // Replace with the actual API endpoint
|
const apiPropertyContactUrl = `https://cloud-api.youraspire.com/PropertyContacts?%24select=ContactID%2CPropertyID`;
|
||||||
|
const apiContactUrl = `https://cloud-api.youraspire.com/Contacts?%24select=ContactID%2CEmail%2CMobilePhone%2CNotes%2CFirstName%2CLastName`;
|
||||||
const headers = {
|
const headers = {
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
'Client-ID': ASPIRE_API_CLIENT_ID,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
//VARIABLES to capture needed data
|
||||||
|
const responseProperty = await axios.get(apiPropertyUrl, { headers });
|
||||||
|
const responsePropertyContact = await axios.get(apiPropertyContactUrl, { headers });
|
||||||
|
const responseContact = await axios.get(apiContactUrl, { headers });
|
||||||
|
const propertyData = responseProperty.data;
|
||||||
|
const propertyContactData = responsePropertyContact.data;
|
||||||
|
const contactData = responseContact.data;
|
||||||
|
|
||||||
const properties = response.data; // Assuming the response directly provides properties
|
// Function to connect propertyData to propertyContactData based on PropertyID and connect propertyContactData to contactData based on ContactID
|
||||||
|
const connectPropertyToContact = property => {
|
||||||
res.render('properties', { properties });
|
const propertyID = property.PropertyID;
|
||||||
} catch (error) {
|
const propertyContacts = propertyContactData.filter(contact => contact.PropertyID === propertyID);
|
||||||
res.status(500).json({ error: error.message });
|
return propertyContacts.map(contact => {
|
||||||
}
|
const contactID = contact.ContactID;
|
||||||
});
|
const contactDetails = contactData.find(c => c.ContactID === contactID);
|
||||||
|
return {
|
||||||
|
...contact,
|
||||||
// DB -GET - WORK TICKET VISIT INDEX
|
contactDetails
|
||||||
app.get('/db/workticketvisits', async (req, res) => {
|
};
|
||||||
const visits = await WorkTicketVisitModel.find({})
|
});
|
||||||
res.render('./workticketvisits/index', { visits })
|
|
||||||
});
|
|
||||||
//DB - SHOW WORKTICKETVISIT/:ID
|
|
||||||
app.get('/db/workticketvisit/:id', async (req, res) => {
|
|
||||||
const visit = await WorkTicketVisitModel.findById(req.params.id)
|
|
||||||
res.render('./workticketvisits/show', { visit })
|
|
||||||
});
|
|
||||||
|
|
||||||
// DB -GET - WORK TICKET INDEX
|
|
||||||
app.get('/db/worktickets', async (req, res) => {
|
|
||||||
const tickets = await WorkTicketModel.find({})
|
|
||||||
res.render('worktickets/index', { tickets })
|
|
||||||
});
|
|
||||||
//DB - SHOW WORKTICKET/:ID
|
|
||||||
app.get('/db/worktickets/:id', async (req, res) => {
|
|
||||||
const ticket = await WorkTicketModel.findById(req.params.id)
|
|
||||||
|
|
||||||
res.render('./worktickets/show', { ticket });
|
|
||||||
});
|
|
||||||
|
|
||||||
//DB - INDEX GET ALL contacts
|
|
||||||
app.get('/db/contacts', async (req, res) => {
|
|
||||||
const contacts = await ContactModel.find({})
|
|
||||||
res.render('./contacts/index', {contacts });
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**** MESSAGING FEATURE ROUTE ****/
|
|
||||||
app.get('/messages', async (req, res)=>{
|
|
||||||
try {
|
|
||||||
const contacts = await ContactModel.find({});
|
|
||||||
|
|
||||||
const propertyContacts = await PropertyContactModel.find({});
|
|
||||||
|
|
||||||
const properties = await PropertyModel.find({});
|
|
||||||
|
|
||||||
const opportunities = await OpportunityModel.find({});
|
|
||||||
const worktickets = await WorkTicketModel.find({});
|
|
||||||
const workVisits = await WorkTicketVisitModel.find({});
|
|
||||||
|
|
||||||
const filteredContacts = workVisits.filter(visit => {
|
|
||||||
return worktickets.some(ticket => ticket.WorkTicketID === visit.WorkTicketID );
|
|
||||||
}).filter(opportunity => {
|
|
||||||
|
|
||||||
return opportunities.some(wonOpportunity => wonOpportunity.OpportunityID === ticket.OpportunityID && opportunity.OpportunityStatusName === "won");
|
|
||||||
}).filter(propertyContact => {
|
|
||||||
|
|
||||||
return propertyContacts.some(propContact => propContact.PropertyID === wonOpportunity.PropertyID );
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
res.render('./messages/index', {
|
|
||||||
filteredContacts,
|
|
||||||
// Include other filtered data in the render object
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
//SendGrid TEST - Navigation will need emails to employee contacts in apsire.
|
|
||||||
app.get('/test', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { ASPIRE_API_CLIENT_ID, ASPIRE_TOKEN, SENDGRID_API_KEY } = process.env;
|
|
||||||
|
|
||||||
|
|
||||||
// Implement logic to fetch appointment data using Axios and API keys
|
|
||||||
const apiUrl = `https://cloud-api.youraspire.com/Contacts?$filter=ContactTypeName eq 'Employee' and LastName ne 'Employee'&$select=FirstName,LastName,Email,CompanyName,Salutation`; // Replace with the actual API endpoint
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
|
||||||
'Client-ID': ASPIRE_API_CLIENT_ID,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await axios.get(apiUrl, { headers });
|
// Mapping propertyData to connect to contactData
|
||||||
|
const connectedData = propertyData.map(property => ({
|
||||||
|
...property,
|
||||||
|
contacts: connectPropertyToContact(property)
|
||||||
|
}));
|
||||||
|
|
||||||
const contacts = response.data;
|
|
||||||
// Assuming the response directly provides contacts
|
|
||||||
|
|
||||||
// Send personalized emails using SendGrid for each contact retrieved
|
res.render('./messages/index', { connectedData });
|
||||||
const sgMail = require('@sendgrid/mail');
|
|
||||||
sgMail.setApiKey(SENDGRID_API_KEY);
|
|
||||||
|
|
||||||
contacts.forEach(async (contact) => {
|
|
||||||
const msg = {
|
|
||||||
to: contact.Email,
|
|
||||||
from: 'info@sprinklersnorthwest.com',
|
|
||||||
subject: 'Bulk Email To Employee Contacts', // Set a subject for the email
|
|
||||||
text: `Hi ${contact.FirstName} ${contact.LastName} of ${contact.CompanyName}, This is an bulk email test to confirm I have pulled contact data from the Aspire API and sent it through sendGrid if this is received please respond to my email landry@shilocode.com when possible thank you Landry-Developer-Shiloh Code`,
|
|
||||||
html: `Hi ${contact.FirstName} ${contact.LastName} of ${contact.CompanyName}, This is an bulk email test to confirm I have pulled contact data from the Aspire API and sent it through sendGrid if this is received please respond to my email landry@shilocode.com when possible thank you Landry-Developer-Shiloh Code`,
|
|
||||||
};
|
|
||||||
|
|
||||||
await sgMail.send(msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({ message: 'Emails sent successfully!' });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//DONT USE THIS
|
||||||
|
//SendGrid TEST - Navigation will need emails to employee contacts in apsire.
|
||||||
|
// app.get('/test', async (req, res) => {
|
||||||
|
// try {
|
||||||
|
// const { ASPIRE_API_CLIENT_ID, ASPIRE_TOKEN, SENDGRID_API_KEY } = process.env;
|
||||||
|
|
||||||
|
|
||||||
|
// // Implement logic to fetch appointment data using Axios and API keys
|
||||||
|
// const apiUrl = `https://cloud-api.youraspire.com/Contacts?$filter=ContactTypeName eq 'Employee' and LastName ne 'Employee'&$select=FirstName,LastName,Email,CompanyName,Salutation`; // Replace with the actual API endpoint
|
||||||
|
// const headers = {
|
||||||
|
// 'Authorization': `Bearer ${ASPIRE_TOKEN}`,
|
||||||
|
// 'Client-ID': ASPIRE_API_CLIENT_ID,
|
||||||
|
// 'Content-Type': 'application/json',
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const response = await axios.get(apiUrl, { headers });
|
||||||
|
|
||||||
|
// const contacts = response.data;
|
||||||
|
// // Assuming the response directly provides contacts
|
||||||
|
|
||||||
|
// // Send personalized emails using SendGrid for each contact retrieved
|
||||||
|
// const sgMail = require('@sendgrid/mail');
|
||||||
|
// sgMail.setApiKey(SENDGRID_API_KEY);
|
||||||
|
|
||||||
|
// contacts.forEach(async (contact) => {
|
||||||
|
// const msg = {
|
||||||
|
// to: contact.Email,
|
||||||
|
// from: 'info@sprinklersnorthwest.com',
|
||||||
|
// subject: 'Bulk Email To Employee Contacts', // Set a subject for the email
|
||||||
|
// text: `Hi ${contact.FirstName} ${contact.LastName} of ${contact.CompanyName}, This is an bulk email test to confirm I have pulled contact data from the Aspire API and sent it through sendGrid if this is received please respond to my email landry@shilocode.com when possible thank you Landry-Developer-Shiloh Code`,
|
||||||
|
// html: `Hi ${contact.FirstName} ${contact.LastName} of ${contact.CompanyName}, This is an bulk email test to confirm I have pulled contact data from the Aspire API and sent it through sendGrid if this is received please respond to my email landry@shilocode.com when possible thank you Landry-Developer-Shiloh Code`,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// await sgMail.send(msg);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// res.json({ message: 'Emails sent successfully!' });
|
||||||
|
// } catch (error) {
|
||||||
|
// res.status(500).json({ error: error.message });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.log(`Server is running on port ${port}`);
|
console.log(`Server is running on port ${port}`);
|
||||||
});
|
});
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<%- include('partials/head') -%>
|
|
||||||
|
|
||||||
<%- include ('partials/navbar') %>
|
|
||||||
|
|
||||||
<h1>Contacts</h1>
|
|
||||||
<ul>
|
|
||||||
<% for (let contact of contacts) { %>
|
|
||||||
<li>
|
|
||||||
<%= contact.FirstName %>
|
|
||||||
</li>
|
|
||||||
<% } %>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<%- include ('partials/footer') %>
|
|
@ -1,24 +0,0 @@
|
|||||||
<%- include('../partials/head') %>
|
|
||||||
|
|
||||||
<%- include ('../partials/navbar') %>
|
|
||||||
<h1>Contacts</h1>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<% for (let contact of contacts){%>
|
|
||||||
<li>
|
|
||||||
<a href="/contact/<%= contact._id %>">
|
|
||||||
<%= contact.CompanyName %>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
|
|
||||||
<%= contact.ContactID %>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<% }%>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<%- include ('../partials/footer') %>
|
|
@ -1,17 +1,60 @@
|
|||||||
<%- include('../partials/head') -%>
|
<%- include('../partials/head') -%> <%- include ('../partials/navbar') %>
|
||||||
|
|
||||||
<%- include ('../partials/navbar') %>
|
<h2>Filtered Property and Contact Data</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Display filtered contacts -->
|
|
||||||
<h2>Filtered Contacts</h2>
|
|
||||||
<ul>
|
|
||||||
<% filteredContacts.forEach(contact => { %>
|
|
||||||
<li><%= contact.FirstName %></li>
|
|
||||||
|
|
||||||
<% }); %>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<%- include ('../partials/footer') %>
|
<div class="container">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th scope="col">Property ID</th>
|
||||||
|
<th scope="col">Property Name</th>
|
||||||
|
<th scope="col">Branch Name</th>
|
||||||
|
<th scope="col">Sequence Number - Date</th>
|
||||||
|
<th scope="col">Property Address</th>
|
||||||
|
<th scope="col">Contact ID</th>
|
||||||
|
|
||||||
|
<th scope="col">First Name</th>
|
||||||
|
<th scope="col">Last Name</th>
|
||||||
|
|
||||||
|
<th scope="col">Contact Email</th>
|
||||||
|
<th scope="col">Mobile Phone</th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% connectedData.forEach(property => { %>
|
||||||
|
<% property.contacts.forEach(contact => { %>
|
||||||
|
<tr>
|
||||||
|
<td><%= property.PropertyID %></td>
|
||||||
|
<td><%= property.PropertyName %></td>
|
||||||
|
<td><%= property.BranchName %></td>
|
||||||
|
|
||||||
|
<td><%= property.SequenceNumber %></td>
|
||||||
|
<td>
|
||||||
|
<%= property.PropertyAddressLine1 %><br>
|
||||||
|
<%= property.PropertyAddressLine2 %>
|
||||||
|
<%= property.PropertyAddressCity%>
|
||||||
|
<%= property.PropertyAddressStateProvinceCode %>
|
||||||
|
<%= property.PropertyAddressZipCode %>
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td><%= contact.ContactID %></td>
|
||||||
|
|
||||||
|
<td><%= contact.contactDetails.FirstName %></td>
|
||||||
|
<td><%= contact.contactDetails.LastName %></td>
|
||||||
|
|
||||||
|
<td><%= contact.contactDetails.Email %></td>
|
||||||
|
<td><%= contact.contactDetails.MobilePhone %></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<% }); %>
|
||||||
|
<% }); %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include ('../partials/footer') %>
|
||||||
|
@ -1,45 +1,28 @@
|
|||||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="#">Brotherton Aspire App</a>
|
<a class="navbar-brand" href="#">Brotherton Aspire App</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
<button
|
||||||
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
class="navbar-toggler"
|
||||||
<span class="navbar-toggler-icon"></span>
|
type="button"
|
||||||
</button>
|
data-bs-toggle="collapse"
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
data-bs-target="#navbarNav"
|
||||||
<ul class="navbar-nav">
|
aria-controls="navbarNav"
|
||||||
<li class="nav-item">
|
aria-expanded="false"
|
||||||
<a class="nav-link active" aria-current="page" href="/">Home</a>
|
aria-label="Toggle navigation"
|
||||||
</li>
|
>
|
||||||
<li class="nav-item">
|
<span class="navbar-toggler-icon"></span>
|
||||||
<a class="nav-link" href="/api/contacts">API Contacts</a>
|
</button>
|
||||||
</li>
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<li class="nav-item">
|
<ul class="navbar-nav">
|
||||||
<a class="nav-link" href="/db/contacts">DB Contacts</a>
|
<li class="nav-item">
|
||||||
</li>
|
<a class="nav-link active" aria-current="page" href="/">Home</a>
|
||||||
<li class="nav-item">
|
</li>
|
||||||
<a class="nav-link" href="/properties">Properties</a>
|
|
||||||
</li>
|
<li class="nav-item">
|
||||||
<li class="nav-item">
|
<a class="nav-link" href="/data-for-messages"> View Filtered API Data</a>
|
||||||
<a class="nav-link" href="/api/worktickets"> API Work Tickets</a>
|
</li>
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
</ul>
|
||||||
<a class="nav-link" href="/api/workticketvisits">API - Work Ticket Vistis</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/workticketvisits">DB - Work Tickets Visits</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/worktickets"> DB Work Tickets</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/messages"> Messages</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/opportunities">opportunities</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
|
</nav>
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<%- include('partials/head') -%>
|
|
||||||
|
|
||||||
<%- include ('partials/navbar') %>
|
|
||||||
|
|
||||||
<h1>properties</h1>
|
|
||||||
<ul>
|
|
||||||
<% for (let property of properties) { %>
|
|
||||||
<li>
|
|
||||||
<%= property.PropertyName %>
|
|
||||||
</li>
|
|
||||||
<% } %>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<%- include ('partials/footer') %>
|
|
@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>work ticket indes</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Work Tickets</h1>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<% for (let ticket of tickets){%>
|
|
||||||
<li>
|
|
||||||
<a href="/worktickets/<%= ticket._id %>">
|
|
||||||
<%= ticket.WorkTicketID %>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<% }%>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>work ticket show</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Show work ticket details</h1>
|
|
||||||
<h3>
|
|
||||||
Ticket ID
|
|
||||||
<%= ticket.WorkTicketID %>
|
|
||||||
</h3>
|
|
||||||
<h4>
|
|
||||||
status
|
|
||||||
<%= ticket.WorkTicketStatusName %>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<%= ticket.SceduledStartDate %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,27 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>work ticket index</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Work Ticket Visits</h1>
|
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<% for (let visit of workticketvisits){%>
|
|
||||||
<li>
|
|
||||||
<a href="/workticketvisit/<%= visit._id %>">
|
|
||||||
<%= visit.WorkTicketVisitID %>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<% }%>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>SHOW work ticket visits </title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h3>Vistit ID
|
|
||||||
<%= visit.WorkTicketVisitID %></h3>
|
|
||||||
|
|
||||||
<h1><%= visit.RouteName %></h1>
|
|
||||||
<h2><%= visit.WorkTicketID %></h2>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||||||
<%- include('/partials/head') %>
|
|
||||||
|
|
||||||
<%- include ('partials/navbar') %>
|
|
||||||
<h1>Work Ticket Visits</h1>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">Work Ticket ID</th>
|
|
||||||
<th scope="col">Scheduled Date</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% for (let i=0; i < workticketvisits.length; i++) { %>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<%= i + 1 %>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<%= workticketvisits[i].WorkTicketID %>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<%= workticketvisits[i].ScheduledDate %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% } %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<%- include ('partials/footer') %>
|
|
Loading…
Reference in New Issue
Block a user