Freelancer Profile Listing
-Template, Database access, Handler -Freelancer Database Table
This commit is contained in:
14
setupdb.sh
14
setupdb.sh
@ -17,6 +17,16 @@ sudo -u postgres psql -c "CREATE TABLE requests(
|
||||
upFrontPaid boolean,
|
||||
onDeliverPaid boolean
|
||||
);
|
||||
|
||||
" cavecomm
|
||||
|
||||
sudo -u postgres psql -c "CREATE TABLE freelancers(
|
||||
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
emailAddress text,
|
||||
name text UNIQUE,
|
||||
generalInformation text,
|
||||
basicInformation text,
|
||||
stripeAccountInformation text,
|
||||
cryptoWalletAddresses text[][],
|
||||
commissionLimit int,
|
||||
templates text[][]
|
||||
);
|
||||
" cavecomm
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <pqxx/pqxx>
|
||||
#include "crow.h"
|
||||
|
||||
@ -12,15 +13,40 @@ namespace Database {
|
||||
//Valid names for the JSON
|
||||
const static std::string JSON_ITEM_NAMES[] = {"id", "customerEmailAddress", "freelancer", "templateName", "currencyPreference", "priceUpFront", "priceOnDeliver", "requestDescription", "accepted", "upFrontInvoiceID", "onDeliverInvoiceID", "upFrontPaid", "onDeliverPaid"};
|
||||
|
||||
//Name and Statement for prepared statement to insert an item into Requests
|
||||
/*
|
||||
* Name and Statement for prepared statement to insert an item into Requests
|
||||
* Takes the name of the freelancer and the template and resolves them to create the request
|
||||
* todo:validate
|
||||
* todo:createAlternative
|
||||
*/
|
||||
const static std::string PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS = "insertItemInRequests";
|
||||
const static std::string SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS = "INSERT INTO requests(id, customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid) VALUES(DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 );";
|
||||
const static std::string SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS = "INSERT INTO requests(id, customerEmailAddress, freelancerid , templateid , currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid) VALUES(DEFAULT, $1, (select id from freelancers where name = $2), (select id from templates where name = $3), $4, $5, $6, $7, $8, $9, $10, $11, $12 );";
|
||||
|
||||
/*
|
||||
* Name and Statement for prepared statement to select an item based on a given ID
|
||||
* Case for boolean return values because the default return value is f/t instead of 0/1 or false/true
|
||||
* todo:validate
|
||||
*/
|
||||
const static std::string PREPARED_STATEMENT_SELECT_ITEM_BY_ID = "selectItemByID";
|
||||
const static std::string SQL_STATEMENT_SELECT_ITEM_BY_ID = "SELECT id , customerEmailAddress, freelancer, templateName, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, (CASE WHEN requests.accepted THEN 1 ELSE 0 END) AS accepted, upFrontInvoiceID, onDeliverInvoiceID, (CASE WHEN requests.upFrontPaid THEN 1 ELSE 0 END) AS upFrontPaid, (CASE WHEN requests.onDeliverPaid THEN 1 ELSE 0 END) AS onDeliverPaid FROM requests WHERE id=$1;";
|
||||
const static std::string SQL_STATEMENT_SELECT_ITEM_BY_ID = "SELECT requests.id , customerEmailAddress, freelancers.name, templates.name, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, (CASE WHEN requests.accepted THEN 1 ELSE 0 END) AS accepted, upFrontInvoiceID, onDeliverInvoiceID, (CASE WHEN requests.upFrontPaid THEN 1 ELSE 0 END) AS upFrontPaid, (CASE WHEN requests.onDeliverPaid THEN 1 ELSE 0 END) AS onDeliverPaid FROM requests INNER JOIN freelancers ON freelancers.id=requests.freelancerID INNER JOIN templates ON templates.id=requests.templateID WHERE requests.id=$1;";
|
||||
|
||||
/*
|
||||
* Name and Statement for prepared statement to select a freelancer based on a given id
|
||||
*/
|
||||
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER = "selectFreelancer";
|
||||
const static std::string SQL_STATEMENT_SELECT_FREELANCER = "select id, name, generalinformation, basicinformation from freelancers WHERE id=$1;";
|
||||
|
||||
/*
|
||||
* Name and Statement for prepared statement to select a freelancers templates based on a given freelancer id
|
||||
*/
|
||||
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES = "selectFreelancerTemplates";
|
||||
const static std::string SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES = "select id, name, content from templates where freelancerid = $1 order by id;";
|
||||
|
||||
/*
|
||||
* Selects freelancers, their basicInfo and if the commissions are closed/open ordered by name.
|
||||
* Delivers if the commission limit has been reached and if the commissions are closed based on the accepted/completed state of the freelancers requests
|
||||
*/
|
||||
const static std::string SQL_Statement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE = "select id, name, basicInformation , (case when (commissionlimit <= (select count(*) as requestCount from requests where requests.accepted = true and requests.completed = false and requests.freelancerid = freelancers.id group by freelancers.id)) then 'Closed' else 'Open' end) as commissionsclosed from freelancers order by name;";
|
||||
|
||||
/*
|
||||
* Struct Representing an item in Requests
|
||||
@ -29,7 +55,9 @@ namespace Database {
|
||||
int id;
|
||||
std::string customerEmailAddress;
|
||||
std::string freelancer;
|
||||
std::string freelancerid;
|
||||
std::string templateName;
|
||||
std::string templateNameid;
|
||||
std::string currencyPreference;
|
||||
std::string priceUpFront;
|
||||
std::string priceOnDeliver;
|
||||
@ -87,6 +115,17 @@ namespace Database {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the prepared statement SELECT_ITEM_BY_ID
|
||||
* Takes an open pqxx::connection
|
||||
*/
|
||||
pqxx::result executeStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE(pqxx::connection &connection) {
|
||||
pqxx::work work(connection);
|
||||
pqxx::result result = work.exec(SQL_Statement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE);
|
||||
work.commit();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the prepared statement SELECT_ITEM_BY_ID
|
||||
* Takes an open pqxx::connection and the id to select by
|
||||
@ -99,6 +138,32 @@ namespace Database {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the prepared statement SELECT_FREELANCER
|
||||
* Takes an open pqxx::connection and the id to select by
|
||||
*/
|
||||
pqxx::result executePreparedStatement_SELECT_FREELANCER(pqxx::connection &connection, int freelancerID) {
|
||||
connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER, SQL_STATEMENT_SELECT_FREELANCER);
|
||||
pqxx::work work(connection);
|
||||
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER, freelancerID);
|
||||
work.commit();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the prepared statement SELECT_FREELANCER_TEMPLATES
|
||||
* Takes an open pqxx::connection and the id to select by
|
||||
*/
|
||||
pqxx::result executePreparedStatement_SELECT_FREELANCER_TEMPLATES(pqxx::connection &connection, int freelancerID) {
|
||||
connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES, SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES);
|
||||
pqxx::work work(connection);
|
||||
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES, freelancerID);
|
||||
work.commit();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* parses the result and returns a JSON
|
||||
* Takes a result and optionally the desired row
|
||||
@ -112,4 +177,29 @@ namespace Database {
|
||||
}
|
||||
return returnJson;
|
||||
}
|
||||
|
||||
/*
|
||||
* parses the result and returns a JSON
|
||||
* parses it fully and returns a JSON containing it at the top or below a variable
|
||||
* takes the result and optionally a name for the top level variable
|
||||
*/
|
||||
crow::json::wvalue convertResultToJSON(pqxx::result &result, std::string jsonName = ""){
|
||||
std::vector<crow::json::wvalue> jsonVector;
|
||||
for (int row = 0; row < result.size(); ++row) {
|
||||
crow::json::wvalue jsonVectorItem;
|
||||
for (int i = 0; i < result.columns(); ++i) {
|
||||
jsonVectorItem[result.column_name(i)] = result.at(row).at(i).c_str();
|
||||
}
|
||||
jsonVector.push_back(jsonVectorItem);
|
||||
}
|
||||
crow::json::wvalue returnJson;
|
||||
if (jsonName != ""){
|
||||
returnJson[jsonName] = crow::json::wvalue(jsonVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnJson = crow::json::wvalue(jsonVector);
|
||||
}
|
||||
return returnJson;
|
||||
}
|
||||
}
|
27
src/main.cpp
27
src/main.cpp
@ -8,10 +8,6 @@ using namespace std;
|
||||
|
||||
int main() {
|
||||
crow::SimpleApp app;
|
||||
//define your endpoint at the root directory
|
||||
CROW_ROUTE(app, "/")([]() {
|
||||
return "Hello world";
|
||||
});
|
||||
|
||||
// CROW_ROUTE(app, "/test.json")
|
||||
// ([](){
|
||||
@ -25,6 +21,29 @@ int main() {
|
||||
string databaseURI = "postgresql://cavecommadmin:cavecomm@localhost:5432/cavecomm";
|
||||
|
||||
|
||||
/*
|
||||
* Freelancer Profile listing for customers
|
||||
*/
|
||||
CROW_ROUTE(app, "/")
|
||||
([databaseURI]() {
|
||||
pqxx::connection databaseConnection(databaseURI);
|
||||
pqxx::result result = Database::executeStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE(databaseConnection);
|
||||
|
||||
auto page = crow::mustache::load("customerIndex_FreelancerListing.html");
|
||||
crow::json::wvalue resultJson = Database::convertResultToJSON(result, "freelancerProfiles");
|
||||
|
||||
crow::mustache::context ctx(resultJson);
|
||||
return page.render(ctx);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CROW_ROUTE(app, "/getEntry/<int>")
|
||||
([databaseURI](int entry) {
|
||||
pqxx::connection databaseConnection(databaseURI);
|
||||
|
39
templates/customerIndex_FreelancerListing.html
Normal file
39
templates/customerIndex_FreelancerListing.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
table {
|
||||
font-family: arial, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid #dddddd;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Freelancer Profiles</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Freelancer</th>
|
||||
<th>Basic Information</th>
|
||||
<th>Commission State</th>
|
||||
</tr>
|
||||
{{#freelancerProfiles}}
|
||||
<tr>
|
||||
<th><a href="/customer/{{name}}/{{id}}">{{name}}</a></th>
|
||||
<th>{{basicinformation}}</th>
|
||||
<th>{{commissionsclosed}}</th>
|
||||
</tr>
|
||||
{{/freelancerProfiles}}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user