ref: 3f83ff6570efee6e4b8f08371ea74bdd7712e30e
parent: fcf082d8955ce3b86e8a7c4742100d8e33c1a1e5
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Aug 6 05:29:38 PDT 2020
add templates
--- a/README.md
+++ /dev/null
@@ -1,5 +1,0 @@
-# templates
-
-These are used to provide the final .html document to the user.
-
-The documentation for them can be found at [html/template](https://golang.org/pkg/html/template)
--- a/doctor/application.tpl
+++ /dev/null
@@ -1,137 +1,0 @@
-{{define "content"}}
- <main>
- {{template "errors" .errors}}
- <label for="application">{{.offer}}</label>
- <form id="application" method="post" enctype="multipart/form-data" boundary="VAL">
- <h4>{{.area}}</h4>
- <fieldset>
- {{template "country" .country}}
- <br><!-- clean up the formatting on some browsers -->
- {{template "specialty" .specialties}}
- </fieldset>
- <h4>{{.gender}}</h4>
- <fieldset>
- <!-- for validation, we use the `name` to get the value associated with the radio cluster. ID is to associate labels -->
- <label for="male">{{.male}}</label>
- <input type="radio" name="gender" id="male" value="male" required>
- <label for="female">{{.female}}</label>
- <input type ="radio" name="gender" id="female" value="female" required>
- </fieldset>
- <h4>{{.documents}}</h4>
- <fieldset>
- <label for="cv">{{.cv}}</label>
- <!-- TODO: Reasonable format list -->
- <input type="file" id="cv" name="cv" accept=".pdf,.doc,.docx,.epub,.rtf,application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document" required>
- <br>
- <label for="diploma">{{.diploma}}</label>
- <input type="file" id="diploma" name="diploma" accept="application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf,.doc,.docx,.epub,.rtf," required multiple>
- </fieldset>
- <!-- To use `required`, both input elements must have the same name -->
- <!-- for validation, we will use the `name` to get the value associated with the radio cluster -->
- <h4>I</h4>
- <fieldset id="q1">
- <p>{{.q1}}</p>
- <label for="q1yes">{{.yes}}</label>
- <input type="radio" name="q1" id="q1yes" value="Yes" required>
- <label for="q1no">{{.no}}</label>
- <input type ="radio" name="q1" id="q1no" value="No" required>
- </fieldset>
- <h4>II</h4>
- <fieldset id="q2">
- <p>{{.q2}}</p>
- <label for="q2yes">{{.yes}}</label>
- <input type="radio" name="q2" id="q2yes" value="Yes" required>
- <label for="q2no">{{.no}}</label>
- <input type="radio" name="q2" id="q2no" value="No" required>
- </fieldset>
- <h4>III</h4>
- <fieldset id="q3">
- <p>{{.q3}}</p>
- <label for="q3yes">{{.yes}}</label>
- <input type="radio" name="q3" id="q3yes" value="Yes" required>
- <label for="q3no">{{.no}}</label>
- <input type ="radio" name="q3" id="q3no" value="No" required>
- </fieldset>
- <h4>IV</h4>
- <fieldset id="q4">
- <p>{{.q4}}</p>
- <label for="q4yes">{{.yes}}</label>
- <input type="radio" name="q4" id="q4yes" value="Yes" required>
- <label for="q4no">{{.no}}</label>
- <input type ="radio" name="q4" id="q4no" value="No" required>
- </fieldset>
- <h4>V</h4>
- <fieldset id="q5" form="application">
- <p>{{.q5}}</p>
- <label for="q5yes">{{.yes}}</label>
- <input type="radio" name="q5" id="q5yes" value="Yes" required>
- <label for="q5no">{{.no}}</label>
- <input type ="radio" name="q5" id="q5no" value="No" required>
- </fieldset>
- <h4>VI</h4>
- <fieldset id="q6">
- <p>{{.q6}}</p>
- <label for="q6yes">{{.yes}}</label>
- <input type="radio" name="q6" id="q6yes" value="Yes" required>
- <label for="q6no">{{.no}}</label>
- <input type ="radio" name="q6" id="q6no" value="No" required>
- </fieldset>
- <h4>VII</h4>
- <fieldset id="q7">
- <p>{{.q7}}</p>
- <label for="q7yes">{{.yes}}</label>
- <input type="radio" name="q7" id="q7yes" value="Yes" required>
- <label for="q7no">{{.no}}</label>
- <input type ="radio" name="q7" id="q7no" value="No" required>
- </fieldset>
- <h4>VIII</h4>
- <fieldset id="q8">
- <p>{{.q8}}</p>
- <label for="q8yes">{{.yes}}</label>
- <input type="radio" name="q8" id="q8yes" value="Yes" required>
- <label for="q8no">{{.no}}</label>
- <input type ="radio" name="q8" id="q8no" value="No" required>
- </fieldset>
- <h4>IX</h4>
- <fieldset id="q9">
- <p>{{.q9}}</p>
- <label for="q9yes">{{.yes}}</label>
- <input type="radio" name="q9" id="q9yes" value="Yes" required>
- <label for="q9no">{{.no}}</label>
- <input type ="radio" name="q9" id="q9no" value="No" required>
- </fieldset>
- <h4>X</h4>
- <fieldset id="q10">
- <p>{{.q10}}</p>
- <label for="q10yes">{{.yes}}</label>
- <input type="radio" name="q10" id="q10yes" value="Yes" required>
- <label for="q10no">{{.no}}</label>
- <input type ="radio" name="q10" id="q10no" value="No" required>
- </fieldset>
- <h4>XI</h4>
- <fieldset id="q11">
- <p>{{.q11}}</p>
- <label for="q11yes">{{.yes}}</label>
- <input type="radio" name="q11" id="q11yes" value="Yes" required>
- <label for="q11no">{{.no}}</label>
- <input type ="radio" name="q11" id="q11no" value="No" required>
- </fieldset>
- <h4>{{.confirm}}</h4>
- <fieldset id="q12">
- <p>{{.q12}}</p>
- <label for="confirm">{{.confirm}}</label>
- <input type="checkbox" name="redFlag" id="confirm" required>
- <br><!-- clean up the formatting on some browsers -->
- </fieldset>
- <h4>{{.user}}</h4>
- <fieldset>
- <label for="email">{{.email}}</label>
- <input type="email" id="email" name="email" required>
- <label for="name">{{.fullname}}</label>
- <input id="name" name="name" required>
- <input type="hidden" name="token" value="{{.token}}">
- </fieldset>
- <button type="submit">{{.submit}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/doctor/bookings.tpl
+++ /dev/null
@@ -1,7 +1,0 @@
-{{define "content"}}
- <main>
- <!-- TODO: We need a calendar element expressed via a table with all upcoming appointments -->
- <h2>YOU CURRENTLY HAVE NO APPOINTMENTS BOOKED</h2>
- <p>If you have agreed to see a patient but do not see them on this page, please refer to the <a href="help.html">Help</a> section.</a>
- </main>
-{{end}}
\ No newline at end of file
--- a/doctor/findpatients.tpl
+++ /dev/null
@@ -1,13 +1,0 @@
-{{define "content"}}
- <main>
-
- <h2>{{.mainHeader}}</h2>
- </main>
- <!-- List patients seeking your specialty
- who are in countries you are able to operate in
- and output them here. This will require some
- more data types included in router/pages.go
- when finally implemented
- -->
-
-{{end}}
\ No newline at end of file
--- a/doctor/profile.tpl
+++ /dev/null
@@ -1,27 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.greetingHeader}}{{.username}}</h2>
- <form method=POST>
- <legend for="dates">{{.appLegend}}</legend>
- <fieldset id="dates">
- <!-- TODO: review better ways to set up chunks of availability
- set up a recurring chunk for a range of hours with weekday checkboxes
- then create a method for editing single days
- this should be flexible enough to get out of the way generally
- but still facilitate granular control when necessary
- -->
- <label for="startDate">{{.from}}</label>
- <input id="startDate" name="startDate" type="datetime-local" required>
- <br>
- <label for="endDate">{{.to}}</label>
- <input id="startDate" name="startDate" type="datetime-local" required>
- <p>{{.bcu}}</p>
- <label for="BTCperU">BTC:</label>
- <input id="BTCperU" id="BTCperU" type="number" min="0.0012" max="1.0" step="0.00001" required>
- </fieldset>
- <button>{{.create}}</button>
- <input type="hidden" name="token" value="{{.token}}">
- <input type="reset">
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/footer.tpl
+++ /dev/null
@@ -1,51 +1,0 @@
-{{define "footer"}}
- <footer>
- <nav class="leftfooter">
- <details open="true">
- <summary>{{.howworks}}</summary>
- <ul>
- <li><a href="{{.basedir}}/help/faq.html">{{.faq}}</a></li>
- <li><a href="{{.basedir}}/help/appointments.html">{{.appts}}</a></li>
- <li><a href="{{.basedir}}/help/contacting.html">{{.proc}}</a></li>
- <li><a href="{{.basedir}}/help/catalog.html">{{.catalog}}</a></li>
- <li><a href="{{.basedir}}/help/paymentmethods.html">{{.payments}}</a></li>
- <li><a href="{{.basedir}}/help/pricesandfees.html">{{.fees}}</a></li>
- <li><a href="{{.basedir}}/help/verification.html">{{.verify}}</a></li>
- </ul>
- </details>
-
- <details open="true">
- <summary>{{.partHead}}</summary>
- <ul>
- <li><a href="{{.basedir}}/partner.html">{{.partner}}</a></li>
- <li><a href="{{.basedir}}/help/provider.html">{{.provider}}</a></li>
- </ul>
- </details>
- </nav>
- <section class="branding">
- <a href="{{.basedir}}/index.html"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380" width="100%"><path d="m360.296875 172.976562-170.632813-170.632812c-.734374-.742188-1.621093-1.328125-2.613281-1.734375-1.953125-.808594-4.152343-.808594-6.113281 0-.984375.40625-1.871094 1-2.609375 1.734375l-170.621094 170.632812-5.359375 5.359376c-3.128906 3.128906-3.128906 8.183593 0 11.3125l175.992188 175.992187c.734375.742187 1.621094 1.328125 2.605468 1.734375.976563.410156 2.015626.617188 3.058594.617188 1.039063 0 2.078125-.207032 3.054688-.617188.984375-.40625 1.871094-.992188 2.605468-1.734375l175.992188-175.992187c3.128906-3.128907 3.128906-8.183594 0-11.3125zm-184.292969 48.777344-151.089844-37.761718 151.089844-37.761719zm16-75.523437 151.085938 37.761719-151.085938 37.761718zm-16-16.476563-136.570312 34.125 136.570312-136.574218zm0 108.476563v102.449219l-136.570312-136.574219zm16 0 136.566406-34.125-136.566406 136.574219zm0-108.476563v-102.449218l136.566406 136.566406zm0 0"/></svg></a>
- <h1>Olmax Medical</h1>
- <banner>{{.banner}}</banner>
- <small>{{.copy}}</small>
- </section>
- <nav class="rightfooter">
- <details open="true">
- <summary>{{.contact}}</summary>
- <ul>
- <li><a href="mailto:olmaxmedical@gmail.com">{{.email}}</a></li>
- <li><a href="tel:1-555-555-5555">{{.phone}}</a></li>
- </ul>
- </details>
- <details open="true">
- <summary>{{.legal}}</summary>
- <ul>
- <li><a href="{{.basedir}}/help/legal.html">{{.legal}}</a></li>
- <li><a href="{{.basedir}}/help/privacy.html">{{.privacy}}</a></li>
- </ul>
- </details>
- </nav>
- </footer>
-</body>
-
-</html>
-{{end}}
\ No newline at end of file
--- a/header.tpl
+++ /dev/null
@@ -1,29 +1,0 @@
-{{define "header"}}
-<!DOCTYPE html>
-<html>
-<head>
- <title>{{.title}}</title>
- {{if .css}}
- <link rel="stylesheet" text="text/css" href="{{.basedir}}/css/{{.css}}">
- {{end}}
- <link rel="icon" type="image/svg+xml" href="{{.basedir}}/favicon.svg">
- <link rel="stylesheet" test="text/css" href="{{.basedir}}/css/default.css">
-
-</head>
-<body>
- <header class="navbar">
- <!-- This changes based on user login status-->
- <nav>
- <ul>
- <li><a href="{{.basedir}}/index.html">{{.home}}</a></li>
- {{if eq .status "true"}}
- <li><a href="{{.basedir}}/profile.html">{{.profile}}</a></li>
- <li><a href="{{.basedir}}/logout.html">{{.logout}}</a></li>
- {{else}}
- <li><a href="{{.basedir}}/signup.html">{{.signup}}</a></li>
- <li><a href="{{.basedir}}/login.html">{{.login}}</a></li>
- {{end}}
- </ul>
- </nav>
- </header>
-{{end}}
\ No newline at end of file
--- a/help/appointments.tpl
+++ /dev/null
@@ -1,42 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.requestHeader}}</h2>
- <h3>{{.statusHeader}}</h3>
- <p>{{.statusBody}}</p>
- <br>
- <h3>{{.scheduleHeader}}</h3>
- <p>{{.scheduleBody}}</p>
- <br>
- <h3>{{.expiresHeader}}</h3>
- <p>{{.expiresBody}}</p>
- <br>
- <h3>{{.emailHeader}}</h3>
- <p>{{.emailBody1}}</p>
- <p>{{.emailBody2}}</p>
- <p style="margin-right: 40px">{{.emailBody3}}</p>
- <p style="margin-right: 40px">{{.emailBody4}}</p>
- <p style="margin-right: 40px">{{.emailBody5}}</p>
- <h4>{{.notifyHeader}}</h4>
- <p>{{.notifyBody}}</p>
- <p style="margin-right: 40px">{{.notifyBody1}}</p>
- <p style="margin-right: 40px">{{.notifyBody2}}</p>
- <p style="margin-right: 40px">{{.notifyBody3}}</p>
- <br>
- <h4>{{.inboxSearchHeader}}</h4>
-
- <p>{{.inboxSearchBody}}</p>
-
- <h4>{{.checkSpamHeader}}</h4>
- <p>{{.checkSpamBody}}</p>
-
- <p style="margin-right: 40px">{{.checkSpamBody1}}</p>
- <p style="margin-right: 40px">{{.checkSpamBody2}}</p>
-
- <p>{{.checkSpamAdd}}</p></br>
- <h4>{{.deliveryHeader}}</h4>
- <br>
- <h4>{{.blockHeader}}</h4>
- <p>{{.blockBody}} <a href="https://www.torproject.org">Tor</a></p>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/catalog.tpl
+++ /dev/null
@@ -1,20 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}<h2>
-<table border="1" cellpadding="8" cellspacing="2">
-<tr bgcolor="gray">
- <th colspan="2">Profile</th>
- <th>Country</th><th>Specialty</th><th>Rate <i>BTC</i></th></th>
- {{range .doctors}}
- <tr valign="top">
- <td><img src="../images/{{.Image}}" /><a href="invoice.html"><h4>{{.Name}}</h4></a></td>
- <td><p>{{.AlmaMater}}</p>
- <p>{{.Residency}}</p>
- <p>{{.Current}}</p>
- <td>{{.Country}}</td>
- <td>{{.Specialty}}</td>
- <td>{{.Rate}}</td>
- {{end}}
- </table>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/contacting.tpl
+++ /dev/null
@@ -1,19 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.contactHeader}}</h2>
- <p>{{.contactBody}}</p>
- <br>
- <h4>{{.scheduleHeader}}</h4>
- <p>{{.scheduleBody}}<p>
- <br>
- <h4>{{.chargedHeader}}</h4>
- <p>{{.chargedBody}}</p>
- <br>
- <h4>{{.anycurrHeader}}</h4>
- <p>{{.anycurrBody}}</p>
- <br>
- <h4>{{.blocksHeader}}</h4>
- <p>{{.blocksBody}} <a href="https://www.torproject.org">Tor</a></p>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/faq.tpl
+++ /dev/null
@@ -1,32 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.helpHeader}}</h2>
- <h4>{{.topics}}</h4>
- <h4>{{.appointmentHeader}}</h4>
- <p>{{.appointmentStatus}}</p>
- <p>{{.appointmentClear}}</p>
- <p>{{.appointmentExpire}}</p>
- <a href="appointments.html">{{.viewall}}</a>
- <h4>{{.paymentHeader}}</h4>
- <p>{{.paymentEdit}}</p>
- <p>{{.paymentBitcoin}}</p>
- <p>{{.paymentBitcoinHow}}</p>
- <p>{{.paymentAdd}}</p>
- <a href="paymentmethods.html">{{.viewall}}</a>
- <h4>{{.verify}}</h4>
- <p>{{.verifyPhone}}</p>
- <p>{{.verifyEmail}}</p>
- <p>{{.verifyLicense}}</p>
- <a href="verification.html">{{.viewall}}</a>
- <h4>{{.priceHeader}}</h4>
- <p>{{.priceDetermined}}</p>
- <p>{{.priceWhen}}</p>
- <p>{{.priceCurrency}}</p>
- <a href="pricesandfees.html">{{.viewall}}</a>
- <h4>{{.contactHeader}}</h4>
- <p>{{.contactStatus}}</p>
- <p>{{.contactHow}}</p>
- <a href="contacting.html">{{.viewall}}</a>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/paymentmethods.tpl
+++ /dev/null
@@ -1,28 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.paymentHeader}}</h2>
- <p>{{.paymentBody}} <a href="https:/bitcoin.org">Bitcoin</a></p>
- <h4>{{.whatBTCHeader}}</h4>
- <p>{{.whatBTCBody}} <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a></p>
- <br>
- <h4>{{.chargedHeader}}</h4>
- <p>{{.chargedBody}}</p>
- <br>
- <h4>{{.anyCoinHeader}}</h4>
- <p>{{.anyCoinBody}}</p>
- <br>
- <h4>{{.editWalletHeader}}</h4>
- <p>{{.editWalletBody}}</p>
- <br>
- <h4>{{.delWalletHeader}}</h4>
- <p>{{.delWalletBody}}</p>
- <p>{{.delWalletBody1}}</p>
- <p>{{.delWalletBody2}}</p>
- <br>
-<p>{{.otherCoinNote}}</p>
- <br>
- <h4>{{.blockedHeader}}</h4>
-<p>{{.blockedBody}}<a href="https://www.torproject.org">Tor</a></p>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/pricesandfees.tpl
+++ /dev/null
@@ -1,19 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.priceHeader}}</h2>
- <p>{{.priceBody}}</p>
- <br>
- <h4>{{.determineHeader}}</h4>
- <p>{{.determineBody}}<p>
- <br>
- <h4>{{.chargedHeader}}</h4>
- <p>{{.chargedBody}}</p>
- <br>
- <h4>{{.currencyHeader}}</h4>
- <p>{{.currencyBody}}</p>
- <br>
- <h4>{{.blockHeader}}</h4>
- <p>{{.blockBody}}<a href="https://www.torproject.org">Tor</a></p>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/provider.tpl
+++ /dev/null
@@ -1,31 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.mainHeader}}</h2>
- <h3>{{.earn}}</h3>
- <form method="post">
- {{template "specialty" .specialties}}
- <button>{{.getStartedHeader}}</button>
- </form>
- <!--TODO change link from TODO.html-->
- <a href="TODO.html">{{.getStartedLink}}</a>
- <h3>{{.providerWhy}} </h3>
- <p>{{.whyText}}</p>
- <h3>{{.control}}</h3>
- <p>{{.controlText}}</p>
- <h3>{{.everyStep}}</h3>
- <p>{{.everyStepText}}</p>
- <h1><strong>{{.provider}}</strong></h1>
- <h1><strong>1</strong></h1>
- <h4>{{.createProfile}}</h4>
- <p>{{.createProfileText}}</p>
- <h1><strong>2</strong></h1>
- <h4>{{.welcomePatient}}</h4>
- <p>{{.welcomePatientText}}</p>
- <h1><strong>3</strong></h1>
- <h4>{{.getPaid}}</h4>
- <p>{{.getPaidText}}</p>
- <h1><strong>{{.safety}}</strong></h1>
- <h3>{{.trust}}</h3>
- <p>{{.trustText}}</p>
- </main>
-{{end}}
\ No newline at end of file
--- a/help/verification.tpl
+++ /dev/null
@@ -1,14 +1,0 @@
-{{define "content"}}
- <main>
- <h1>{{.mainHeader}}</h1>
- <h2>{{.verifyHeader}}</h2>
- <p>{{.verifyBody}}</p>
- <h4>{{.phoneHeader}}</h4>
- <p>{{.phoneBody}}</p>
- <h4>{{.noNoteHeader}}</h4>
- <p>{{.noNoteBody}}<a href="{{.basedir}}/appointmentRequests.html">Appointment Requests</a></p>
-
- <h4>{{.blockHeader}}</h4>
- <p>{{.blockBody}}<a href="https://www.torproject.org">Tor</a></p>
- </main>
-{{end}}
\ No newline at end of file
--- a/index.tpl
+++ /dev/null
@@ -1,24 +1,0 @@
-{{define "content"}}
- <main>
- <section>
- <h2>{{.whoWeAre}}</h2>
- <p>{{.aboutUs}}</p>
- </section>
- <section>
- <h2>{{.secondOpinions}}</h2>
- <p>{{.fromHome}}</p>
- </section>
- <section>
- <h2>{{.anonymity}}</h2>
- <p>{{.anonText}}</p>
- </section>
- <section>
- <h2>{{.wholeWorld}}</h2>
- <p>{{.wholeWorldText}}</p>
- </section>
- <section>
- <h2>{{.payment}}</h2>
- <p>{{.paymentText}}</p>
- </section>
- </main>
-{{end}}
\ No newline at end of file
--- a/layout.tpl
+++ /dev/null
@@ -1,7 +1,0 @@
-{{define "layout"}}
-{{template "header" .header}}
- <div class="content">
-{{template "content" .}}
- </div>
-{{template "footer" .footer}}
-{{end}}
\ No newline at end of file
--- a/login.tpl
+++ /dev/null
@@ -1,14 +1,0 @@
-{{define "content"}}
- <main>
- <h3>{{if .redirect }}{{.continue}}{{else}}{{.greeting}}{{end}}</h3>
- {{template "errors" .errors}}
- <form method="post" action="login.html">
- <label for="email">{{.email}}*</label>
- <input type="email" name="email" id="email" required autocomplete="off"/><br>
- <label for="pass">{{.password}}*</label>
- <input type="password" name="pass" id="pass" minlength="8" required autocomplete="off"/><br>
- <p class="forgot"><a href="resetpassword.html">{{.forgotPassword}}</a></p>
- <button type="submit" class="button button-block"/>{{.login}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/messages.tpl
+++ /dev/null
@@ -1,6 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.mainHeader}}</h2>
- <p>{{.messages}}</p>
- </main>
-{{end}}
\ No newline at end of file
--- a/newpassword.tpl
+++ /dev/null
@@ -1,15 +1,0 @@
-{{define "content"}}
- <main>
- <h3>{{.reset}}</h3>
-
- {{template "errors" .errors}}
- <form method="post" action="{{.basedir}}/newpassword.html">
- <input type="hidden" name="token" value="{{.token}}"/>
- <label for="password">{{.password}}*</label>
- <input type="password" name="password" id="password" required autocomplete="off"/><br>
- <laber for="reenter">{{.reenter}}*</label>
- <input type="password" name="reenter" id="reenter" required autocomplete="off"/><br>
- <button type="submit" class="button button-block"/>{{.update}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/patient/appointments.tpl
+++ /dev/null
@@ -1,7 +1,0 @@
-{{define "content"}}
- <main>
- <!-- TODO: List each upcoming appointment, one per row as <details> -->
- <h2>{{.mainHeader}}</h2>
- <p>{{.mainBody}}</a>
- </main>
-{{end}}
\ No newline at end of file
--- a/patient/offer.tpl
+++ /dev/null
@@ -1,18 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.mainHeader}}</h2>
- <form action="findspecialty">
- {{template "specialty" .specialties}}
- <br/>
- <label for="Amount">{{.bcu}} <i>({{.rate}})</i></label>
- <input type="text" name="Amount" size="15" maxlength="10" />
- <h3>{{.dates}}</h3>
- <label for="startDate">{{.from}}</label>
- <input id="startDate" type="date" name="startDate" required>
- <label for="endDate">{{.to}}</label>
- <input id="endDate" type="date" name="endDate" required>
- <br/>
- <button>{{.deploy}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/patient/profile.tpl
+++ /dev/null
@@ -1,8 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.greetingHeader}}{{.username}}</h2>
- <fieldset id="find-dr">
- <!-- list appointments here -->
- </fieldset>
- </main>
-{{end}}
\ No newline at end of file
--- a/patient/symptoms.tpl
+++ /dev/null
@@ -1,58 +1,0 @@
-{{define "content"}}
- <!-- This will be emailed directly to the physician on completion
- it is locally validated, but never locally stored
- -->
- <main>
- <h2>{{.createHeader}}</h2>
- <hr/>
- <h2>{{.formHeader}}</h2>
- <form action="post">
- <label for="bday">{{.birthdate}}</label>
- <input type="date" name="bday"/>
- <label for="gender">{{.gender}}</label>
- <input type="radio" name="gender" value="male"/>{{.male}}
- <input type ="radio" name="gender" value="female"/>{{.female}}
- <label for="reason">{{.visitReason}}</label>
- <textarea name="reason" row="6" cols="50"></textarea>
- <label for="onset">{{.symptomStart}}</label>
- <input type="date" name="onset"/>
- <label for="location">{{.symptomArea}}</label>
- <input type="text" id="location"/>
- <laber for="duration">{{.symptomDuration}}</label>
- <input type="number" min="0" id="duration"/>
- <label for="characteristic">{{.symptomDescription}}</label>
- <input type="text" id="characteristic"/>
- <label for="aggreAlevi">{{.symptomAugment}}</label>
- <input type="text" id="aggreAlevi"/>
- <label for="radiate">{{.symptomProliferation}}</label>
- <input type="text" id="radiate"/>
- <label for="treatments">{{.symptomTreatment}}</label>
- <textarea name="treatments" row="6" cols="50"></textarea>
- <fieldset>
- <legend>{{.legend}}</legend>
- <!--"ros" means Review of Systems -->
- <input type="radio" name="ros" id="feversChills" value="feversChills" />
- <label for="feversChills">{{.feversChills}}</label><br />
- <input type="radio" name="ros" id="wtGainLoss" value="wtGainLoss" />
- <label for="wtGainLoss">{{.wtGainLoss}}</label><br />
- <input type="radio" name="ros" id="vison" value="vision" />
- <label for="vision">{{.vision}}</label><br />
- <input type="radio" name="ros" id="lung" value="lung" />
- <label for="lung">{{.lung}}</label><br />
- <input type="radio" name="ros" id="heart" value="heart" />
- <label for="heart">{{.heart}}</label><br />
- <input type="radio" name="ros" id="bowel" value="bowel" />
- <label for="bowel">{{.bowel}}</label><br />
- <input type="radio" name="ros" id="renal" value="renal" />
- <label for="renal">{{.renal}}</label><br />
- <input type="radio" name="ros" id="musSkel" value="musSkel" />
- <label for="musSkel">{{.musSkel}}</label><br />
- <input type="radio" name="ros" id="neuro" value="neuro" />
- <label for="neuro">{{.neuro}}</label><br />
- <input type="radio" name="ros" id="psych" value="psych">
- <label for="psych">{{.psych}}<br/>
- </fieldset>
- <input type="submit" value="submit">
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/plugins/appointments.go
+++ /dev/null
@@ -1,25 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/router"
-)
-
-// AddAppointment registers an appointment into the appointment book
-// TODO(halfwit) message/email client to fill out Symptoms form
-const AddAppointment router.PluginMask = 1 << 1
-
-func init() {
- b := &router.Plugin{
- Name: "Add Appointments",
- Run: nil,
- Validate: addAppt,
- }
- router.AddPlugin(b, AddAppointment)
-}
-
-func addAppt(s *router.Request) error {
- // get &id=
- // Auth user and requisite key
- // TODO(halfwit) create unique key in patient/appointments
- return nil
-}
--- a/plugins/appointments.tpl
+++ /dev/null
@@ -1,3 +1,0 @@
-{{define "appointments"}}
-<!-- appointments here -->
-{{end}}
\ No newline at end of file
--- a/plugins/bookings.go
+++ /dev/null
@@ -1,22 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/router"
-)
-
-// ListBookings retreives a list of all upcoming bookings for a given doctor
-const ListBookings router.PluginMask = 1 << 2
-
-func init() {
- b := &router.Plugin{
- Name: "List Bookings",
- Run: nil,
- Validate: listBookings,
- }
- router.AddPlugin(b, ListBookings)
-}
-
-func listBookings(s *router.Request) error {
-
- return nil
-}
--- a/plugins/bookings.tpl
+++ /dev/null
@@ -1,3 +1,0 @@
-{{define "bookings"}}
-<!-- bookings form here -->
-{{end}}
\ No newline at end of file
--- a/plugins/countries.go
+++ /dev/null
@@ -1,96 +1,0 @@
-package plugins
-
-import (
- "fmt"
- "sort"
- "strings"
-
- "github.com/olmaxmedical/router"
- "github.com/pariz/gountries"
- "golang.org/x/text/message"
-)
-
-// Countries - Populate a localized spinner to select country
-const Countries router.PluginMask = 1 << 3
-
-// Country - Mapping token to internationalized country code
-type Country struct {
- ID string
- Name string
-}
-
-type countries struct {
- list []gountries.Country
-}
-
-var cache *countries
-
-func init() {
- var l []gountries.Country
- c := gountries.New()
- for _, c := range c.FindAllCountries() {
- l = append(l, c)
- }
- cache = &countries{
- list: l,
- }
- sort.Sort(cache)
- b := &router.Plugin{
- Name: "country",
- Run: listCountries,
- Validate: validateCountries,
- }
- router.AddPlugin(b, Countries)
-}
-
-// Len - For Sort implementation
-func (c *countries) Len() int {
- return len(c.list)
-}
-
-// Less - For Sort implementation
-func (c *countries) Less(i, j int) bool {
- switch strings.Compare(c.list[i].Name.Common, c.list[j].Name.Common) {
- case -1:
- return true
- default:
- return false
- }
-}
-
-// Swap - For Sort implementation
-func (c *countries) Swap(i, j int) {
- tmp := c.list[i]
- c.list[i] = c.list[j]
- c.list[j] = tmp
-}
-
-func listCountries(r *router.Request) map[string]interface{} {
- p := r.Printer()
- // TODO(halfwit): Use Request to get a localized country name
- c := make(map[string]interface{})
- c["label"] = p.Sprint("Select country/countries")
- for _, item := range cache.list {
- c[item.Name.Common] = item.Name.Common
- }
- return c
-}
-
-func validateCountries(r *router.Request) error {
- s := r.Request()
- for _, c := range s.PostFormValue("country") {
- if msg := checkCountry(r.Printer(), c); msg != nil {
- return msg
- }
- }
- return nil
-}
-
-func checkCountry(p *message.Printer, country rune) error {
- for _, item := range cache.list {
- if item.Name.Common == string(country) {
- return nil
- }
- }
- return fmt.Errorf("%s", p.Sprint("No country entered/nil value entered"))
-}
--- a/plugins/countries.tpl
+++ /dev/null
@@ -1,8 +1,0 @@
-{{define "country"}}
-<label for="country">{{.label}}</label>
-<select name="country" id="country" multiple required>
- {{range $id, $name := .}}
- <option value="{{$id}}">{{$name}}</option>
- {{end}}
-</select>
-{{end}}
--- a/plugins/doctor.go
+++ /dev/null
@@ -1,55 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/router"
-)
-
-// ListDoctors - Bitmask to list doctors of in client country
-const ListDoctors router.PluginMask = 1 << 4
-
-type doctor struct {
- Image string
- AlmaMater string
- Name string
- Residency string
- Current string
- Country string
- Specialty string
- Rate string
-}
-
-func init() {
- b := &router.Plugin{
- Name: "doctors",
- Run: ListDocs,
- Validate: nil,
- }
- router.AddPlugin(b, ListDoctors)
-}
-
-// ListDocs - Query db and return list of doctors in country
-// These may need eventual localization for any bilingual doctors we have
-func ListDocs(r *router.Request) map[string]interface{} {
- return map[string]interface{}{
- "Mark Abuzamzam, MD": &doctor{
- Image: "AbuzamzamMD.jpg",
- AlmaMater: "University of Southern California School of Medicine",
- Residency: "University of Southern California, San Diego. Internal Medicine Residency",
- Name: "Mark Abuzamzam, MD",
- Current: "Current Faculty at University of California Irvine Program Director",
- Country: "United States of America",
- Specialty: "Internal Medicine and Addictions Medicine",
- Rate: "0.0013 BTC",
- },
- "Martha Woodfin, MD": &doctor{
- Image: "WoodfinMD.jpg",
- Name: "Martha Woodfin, MD",
- AlmaMater: "University Seoul School of Medicine",
- Residency: "University of Las Vegas Nevada, Pediatric Medicine Residency",
- Current: "Current Staff at Mercy Hospital Jackson NC",
- Country: "United States of America",
- Specialty: "Internal Medicine",
- Rate: "0.0011 BTC",
- },
- }
-}
--- a/plugins/email.go
+++ /dev/null
@@ -1,83 +1,0 @@
-package plugins
-
-import (
- "errors"
- "log"
- "mime/multipart"
-
- "github.com/olmaxmedical/email"
- "github.com/olmaxmedical/router"
-)
-
-// EmailForm - Patient form to gmail
-const EmailForm router.PluginMask = 1 << 5
-
-// SendSignup - Send account creation validation email
-const SendSignup router.PluginMask = 1 << 6
-
-// SendReset - Send password reset email
-const SendReset router.PluginMask = 1 << 7
-
-func init() {
- b := &router.Plugin{
- Name: "emailform",
- Run: nil,
- Validate: emailForm,
- }
- router.AddPlugin(b, EmailForm)
- c := &router.Plugin{
- Name: "signupEmail",
- Run: nil,
- Validate: signupEmail,
- }
- router.AddPlugin(c, SendSignup)
- d := &router.Plugin{
- Name: "resetPassword",
- Run: nil,
- Validate: resetPassword,
- }
- router.AddPlugin(d, SendReset)
-}
-
-func signupEmail(s *router.Request) error {
- r := s.Request()
- first := r.PostFormValue("fname")
- last := r.PostFormValue("lname")
- address := r.PostFormValue("email")
- pass := r.PostFormValue("pass")
- email.SendSignup(first, last, address, pass, s.Printer())
- return nil
-}
-
-func resetPassword(s *router.Request) error {
- p := s.Printer()
- r := s.Request()
- email.SendReset(r.PostFormValue("email"), p)
- return nil
-}
-
-func emailForm(s *router.Request) error {
- p := s.Printer()
- r := s.Request()
- r.ParseMultipartForm(10 << 20) // parse up to 10MB
- if r.PostFormValue("name") == "" || r.PostFormValue("email") == "" {
- return errors.New(p.Sprint("Missing name or email in form. Please contact us at olmaxmedical@gmail.com"))
- }
- if b, ok := r.Form["sendto"]; !ok || b[0] == "" {
- return errors.New(p.Sprint("Missing value for target email. Please contact us at olmaxmedical.gmail.com"))
- }
- attachments := make(map[string]multipart.File)
- m := r.MultipartForm
- for _, headers := range m.File {
- for _, header := range headers {
- file, err := header.Open()
- if err != nil { //non fatal, log any oddities and continue
- log.Println(err)
- continue
- }
- attachments[header.Filename] = file
- }
- }
- email.SendForm(r.Form, p, attachments)
- return nil
-}
--- a/plugins/errors.go
+++ /dev/null
@@ -1,28 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/router"
-)
-
-// FormErrors - A list of errors present on a POST request
-const FormErrors router.PluginMask = 1 << 8
-
-func init() {
- b := &router.Plugin{
- Name: "errors",
- Run: GetFormErrors,
- Validate: nil,
- }
- router.AddPlugin(b, FormErrors)
-}
-
-// GetFormErrors - return the client a list of any errors in the form
-func GetFormErrors(r *router.Request) map[string]interface{} {
- s := r.Session()
- if s == nil {
- return nil
- }
- return map[string]interface{}{
- "errors": s.Get("errors"),
- }
-}
--- a/plugins/errors.tpl
+++ /dev/null
@@ -1,5 +1,0 @@
-{{define "errors"}}
-{{range .}}
-<p style="color: red" class="errtext">{{.}}</p>
-{{end}}
-{{end}}
\ No newline at end of file
--- a/plugins/messages.go
+++ /dev/null
@@ -1,29 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/router"
-)
-
-// Messages - list all messages by key for use in a message template
-const Messages router.PluginMask = 1 << 9
-
-func init() {
- b := &router.Plugin{
- Name: "messages",
- Run: GetMessages,
- Validate: nil,
- }
- router.AddPlugin(b, Messages)
-}
-
-// GetMessages - return a map of message structs
-func GetMessages(r *router.Request) map[string]interface{} {
- s := r.Session()
- if s == nil {
- return nil
- }
- return map[string]interface{}{
- // No, this won't actually do anything.
- "messages": s.Get("messages"),
- }
-}
--- a/plugins/offers.go
+++ /dev/null
@@ -1,19 +1,0 @@
-package plugins
-
-import "github.com/olmaxmedical/router"
-
-// MakeOffer - Request a time slot with doctor
-const MakeOffer router.PluginMask = 1 << 10
-
-func init() {
- b := &router.Plugin{
- Name: "offer",
- Run: nil,
- Validate: offer,
- }
- router.AddPlugin(b, MakeOffer)
-}
-
-func offer(s *router.Request) error {
- return nil
-}
--- a/plugins/password.go
+++ /dev/null
@@ -1,62 +1,0 @@
-package plugins
-
-import (
- "errors"
-
- "github.com/olmaxmedical/database"
- "github.com/olmaxmedical/router"
-)
-
-// ValidateLogin - Check user/pass combo exists
-const ValidateLogin router.PluginMask = 1 << 11
-
-// ResetPassword - Update database entry for password
-const ResetPassword router.PluginMask = 1 << 12
-
-func init() {
- b := &router.Plugin{
- Name: "login",
- Run: nil,
- Validate: login,
- }
- router.AddPlugin(b, ValidateLogin)
- c := &router.Plugin{
- Name: "setPassword",
- Run: nil,
- Validate: setPass,
- }
- router.AddPlugin(c, ResetPassword)
-}
-
-func login(s *router.Request) error {
- r := s.Request()
- us := s.Session()
- p := s.Printer()
- user := r.PostFormValue("email")
- pass := r.PostFormValue("pass")
- if database.ValidateLogin(user, pass) {
- us.Set("username", user)
- us.Set("login", "true")
- us.Set("role", database.UserRole(user))
- us.Set("token", database.NewToken())
- return nil
- }
- return errors.New(p.Sprint("Invalid login"))
-}
-
-func setPass(s *router.Request) error {
- r := s.Request()
- p := s.Printer()
-
- pass := r.PostFormValue("password")
- repeat := r.PostFormValue("reenter")
- if pass != repeat {
- return errors.New(p.Sprint("Passwords do not match"))
- }
- token := r.PostFormValue("token")
- if !database.FindTempEntry(token) {
- return errors.New(p.Sprint("Session expired"))
- }
- database.UpdateUserPassword(token, pass)
- return nil
-}
--- a/plugins/search.go
+++ /dev/null
@@ -1,20 +1,0 @@
-package plugins
-
-import "github.com/olmaxmedical/router"
-
-// Search - generic search for doctors in area
-const Search router.PluginMask = 1 << 13
-
-func init() {
- b := &router.Plugin{
- Name: "search",
- Run: nil,
- Validate: search,
- }
- router.AddPlugin(b, Search)
-}
-
-// Stuuuuubbb
-func search(r *router.Request) error {
- return nil
-}
--- a/plugins/search.tpl
+++ /dev/null
@@ -1,3 +1,0 @@
-{{define "search"}}
-<!-- Search bar here -->
-{{end}}
\ No newline at end of file
--- a/plugins/services.go
+++ /dev/null
@@ -1,114 +1,0 @@
-package plugins
-
-import (
- "fmt"
-
- "github.com/olmaxmedical/router"
-)
-
-// Services - Bitmask to list services in native language
-const Services router.PluginMask = 1 << 14
-
-func init() {
- b := &router.Plugin{
- Name: "specialties",
- Run: ListServices,
- Validate: ValidateServices,
- }
- router.AddPlugin(b, Services)
-}
-
-// ValidateServices - Ensure the specialties entered exist in our map
-func ValidateServices(r *router.Request) error {
- s := r.Request()
- var errs []string
- for _, entry := range s.PostFormValue("specialty") {
- switch string(entry) {
- case "acutepain":
- case "anasthesiology":
- case "bariatric":
- case "cardiology":
- case "chiropractic":
- case "chronic":
- case "critcare":
- case "dermatology":
- case "emergency":
- case "endocrinology":
- case "otolaringology":
- case "familymedicine":
- case "gastro":
- case "headneck":
- case "hematology":
- case "hepatology":
- case "hyperbaric":
- case "immunology":
- case "diseases":
- case "internal":
- case "neonatal":
- case "nephrology":
- case "neurology":
- case "neurosurgery":
- case "obstetrics":
- case "occupational":
- case "opthamology":
- case "orthopedics":
- case "palliative":
- case "pediatrics":
- case "podiatry":
- case "pulmonology":
- case "radiology":
- case "radiation":
- case "transplants":
- continue
- default:
- errs = append(errs, fmt.Sprintf("Unknown entry: %q\n", entry))
- }
- if len(errs) > 0 {
- return fmt.Errorf("%s", errs)
- }
- }
- return nil
-}
-
-// ListServices - return a list of native language representations of our medical fields
-func ListServices(r *router.Request) map[string]interface{} {
- p := r.Printer()
- return map[string]interface{}{
- "label": p.Sprint("Select specialty/specialties"),
- "acutepain": p.Sprint("Acute Pain Medicine"),
- "anesthesiology": p.Sprint("Anesthesiology"),
- "bariatric": p.Sprint("Bariatric Surgery"),
- "cardiology": p.Sprint("Cardiology"),
- "chiropractic": p.Sprint("Chiropractics"),
- "chronic": p.Sprint("Chronic Pain"),
- "critcare": p.Sprint("Critical Care"),
- "dermatology": p.Sprint("Dermatology"),
- "emergency": p.Sprint("Emergency Medicine"),
- "endocrinology": p.Sprint("Endocrinology"),
- "otolaringology": p.Sprint("Ear Nose and Throat"),
- "familymedicine": p.Sprint("Family Medicine"),
- "gastro": p.Sprint("Gastrointestinology"),
- "headneck": p.Sprint("Head and Neck"),
- "hematology": p.Sprint("Hematology and Oncology"),
- "hepatology": p.Sprint("Hepatology"),
- "hyperbaric": p.Sprint("Hyperbaric"),
- "immunology": p.Sprint("Immunology"),
- "diseases": p.Sprint("Infectious Diseases"),
- "internal": p.Sprint("Internal Medicine"),
- "neonatal": p.Sprint("Neonatology"),
- "nephrology": p.Sprint("Nephrology"),
- "neurology": p.Sprint("Neurology"),
- "neurosurgery": p.Sprint("Neurosurgery"),
- "obstetrics": p.Sprint("Obstetrics and Gynecology"),
- "occupational": p.Sprint("Occupational Medicine"),
- "opthamology": p.Sprint("Opthamology"),
- "orthopedics": p.Sprint("Orthopedic Surgery"),
- "palliative": p.Sprint("Palliative Care"),
- "pediatrics": p.Sprint("Pediatrics"),
- "podiatry": p.Sprint("Podiatry"),
- "pulmonology": p.Sprint("Pulmonology"),
- "radiology": p.Sprint("Radiology"),
- "radiation": p.Sprint("Radiaton Oncology"),
- "transplants": p.Sprint("Transplant Surgery"),
- }
-}
--- a/plugins/specialties.tpl
+++ /dev/null
@@ -1,8 +1,0 @@
-{{define "specialty"}}
-<label for="Specialty">{{.label}}</label>
-<select name="Specialty" id="specialty" multiple required>
- {{range $id, $name := .}}
- <option value="{{$id}}">{{$name}}</option>
- {{end}}
-</select>
-{{end}}
\ No newline at end of file
--- a/plugins/tokens.go
+++ /dev/null
@@ -1,29 +1,0 @@
-package plugins
-
-import (
- "github.com/olmaxmedical/database"
- "github.com/olmaxmedical/router"
-)
-
-// FormToken - A database-persisted one time use token to relate forms to POST requests
-const FormToken router.PluginMask = 1 << 15
-
-func init() {
- c := &router.Plugin{
- Name: "formToken",
- Run: newFormToken,
- Validate: validateToken,
- }
- router.AddPlugin(c, FormToken)
-}
-
-func validateToken(r *router.Request) error {
- return database.ValidateToken(r.Request(), r.Session())
-}
-
-// TODO(halfwit) - database
-func newFormToken(r *router.Request) map[string]interface{} {
- return map[string]interface{}{
- "token": database.NewToken(),
- }
-}
--- a/resetpassword.tpl
+++ /dev/null
@@ -1,12 +1,0 @@
-{{define "content"}}
- <main>
- <h3>{{.reset}}</h3>
- {{template "errors" .errors}}
- <p>{{.resettext}}
- <form method="post" action="resetpassword.html">
- <label for="email">{{.email}}*</label>
- <input type="email" name="email" id="email" required autocomplete="off"/><br>
- <button type="submit" class="button button-block"/>{{.sendreset}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/signup.tpl
+++ /dev/null
@@ -1,17 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.mainHeader}}</h2>
- {{template "errors" .errors}}
- <form method="post" action="signup.html">
- <label for="fname">{{.fname}}*</label>
- <input type="text" name="fname" id="fname" placeholder="{{.fnameph}}" required autocomplete="off" autofocus/><br>
- <label for="lname">{{.lname}}*</label>
- <input type="text" name="lname" id="lname" placeholder="{{.lnameph}}" required autocomplete="off"/><br>
- <label for="email">{{.email}}*</label>
- <input type="email" name="email" id="email" placeholder="{{.emailph}}" required autocomplete="off"/><br>
- <label for="pass">{{.pass}}*</label>
- <input type="password" name="pass" id="pass" minlength="8" placeholder="{{.passph}}" required autocomplete="off"/><br>
- <button type="submit" class="button button-block"/>{{.gobutton}}</button>
- </form>
- </main>
-{{end}}
\ No newline at end of file
--- a/template_test.go
+++ /dev/null
@@ -1,28 +1,0 @@
-package template
-
-import (
- "testing"
- "text/template"
-)
-
-func TestTemplates(t *testing.T) {
- if _, e := template.ParseGlob("*.tpl"); e != nil {
- t.Error(e)
- }
-
- if _, e := template.ParseGlob("help/*.tpl"); e != nil {
- t.Error(e)
- }
-
- if _, e := template.ParseGlob("doctor/*.tpl"); e != nil {
- t.Error(e)
- }
-
- if _, e := template.ParseGlob("patient/*.tpl"); e != nil {
- t.Error(e)
- }
-
- if _, e := template.ParseGlob("plugins/*.tpl"); e != nil {
- t.Error(e)
- }
-}
--- /dev/null
+++ b/templates/README.md
@@ -1,0 +1,5 @@
+# templates
+
+These are used to provide the final .html document to the user.
+
+The documentation for them can be found at [html/template](https://golang.org/pkg/html/template)
--- /dev/null
+++ b/templates/doctor/application.tpl
@@ -1,0 +1,137 @@
+{{define "content"}}
+ <main>
+ {{template "errors" .errors}}
+ <label for="application">{{.offer}}</label>
+ <form id="application" method="post" enctype="multipart/form-data" boundary="VAL">
+ <h4>{{.area}}</h4>
+ <fieldset>
+ {{template "country" .country}}
+ <br><!-- clean up the formatting on some browsers -->
+ {{template "specialty" .specialties}}
+ </fieldset>
+ <h4>{{.gender}}</h4>
+ <fieldset>
+ <!-- for validation, we use the `name` to get the value associated with the radio cluster. ID is to associate labels -->
+ <label for="male">{{.male}}</label>
+ <input type="radio" name="gender" id="male" value="male" required>
+ <label for="female">{{.female}}</label>
+ <input type ="radio" name="gender" id="female" value="female" required>
+ </fieldset>
+ <h4>{{.documents}}</h4>
+ <fieldset>
+ <label for="cv">{{.cv}}</label>
+ <!-- TODO: Reasonable format list -->
+ <input type="file" id="cv" name="cv" accept=".pdf,.doc,.docx,.epub,.rtf,application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document" required>
+ <br>
+ <label for="diploma">{{.diploma}}</label>
+ <input type="file" id="diploma" name="diploma" accept="application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.pdf,.doc,.docx,.epub,.rtf," required multiple>
+ </fieldset>
+ <!-- To use `required`, both input elements must have the same name -->
+ <!-- for validation, we will use the `name` to get the value associated with the radio cluster -->
+ <h4>I</h4>
+ <fieldset id="q1">
+ <p>{{.q1}}</p>
+ <label for="q1yes">{{.yes}}</label>
+ <input type="radio" name="q1" id="q1yes" value="Yes" required>
+ <label for="q1no">{{.no}}</label>
+ <input type ="radio" name="q1" id="q1no" value="No" required>
+ </fieldset>
+ <h4>II</h4>
+ <fieldset id="q2">
+ <p>{{.q2}}</p>
+ <label for="q2yes">{{.yes}}</label>
+ <input type="radio" name="q2" id="q2yes" value="Yes" required>
+ <label for="q2no">{{.no}}</label>
+ <input type="radio" name="q2" id="q2no" value="No" required>
+ </fieldset>
+ <h4>III</h4>
+ <fieldset id="q3">
+ <p>{{.q3}}</p>
+ <label for="q3yes">{{.yes}}</label>
+ <input type="radio" name="q3" id="q3yes" value="Yes" required>
+ <label for="q3no">{{.no}}</label>
+ <input type ="radio" name="q3" id="q3no" value="No" required>
+ </fieldset>
+ <h4>IV</h4>
+ <fieldset id="q4">
+ <p>{{.q4}}</p>
+ <label for="q4yes">{{.yes}}</label>
+ <input type="radio" name="q4" id="q4yes" value="Yes" required>
+ <label for="q4no">{{.no}}</label>
+ <input type ="radio" name="q4" id="q4no" value="No" required>
+ </fieldset>
+ <h4>V</h4>
+ <fieldset id="q5" form="application">
+ <p>{{.q5}}</p>
+ <label for="q5yes">{{.yes}}</label>
+ <input type="radio" name="q5" id="q5yes" value="Yes" required>
+ <label for="q5no">{{.no}}</label>
+ <input type ="radio" name="q5" id="q5no" value="No" required>
+ </fieldset>
+ <h4>VI</h4>
+ <fieldset id="q6">
+ <p>{{.q6}}</p>
+ <label for="q6yes">{{.yes}}</label>
+ <input type="radio" name="q6" id="q6yes" value="Yes" required>
+ <label for="q6no">{{.no}}</label>
+ <input type ="radio" name="q6" id="q6no" value="No" required>
+ </fieldset>
+ <h4>VII</h4>
+ <fieldset id="q7">
+ <p>{{.q7}}</p>
+ <label for="q7yes">{{.yes}}</label>
+ <input type="radio" name="q7" id="q7yes" value="Yes" required>
+ <label for="q7no">{{.no}}</label>
+ <input type ="radio" name="q7" id="q7no" value="No" required>
+ </fieldset>
+ <h4>VIII</h4>
+ <fieldset id="q8">
+ <p>{{.q8}}</p>
+ <label for="q8yes">{{.yes}}</label>
+ <input type="radio" name="q8" id="q8yes" value="Yes" required>
+ <label for="q8no">{{.no}}</label>
+ <input type ="radio" name="q8" id="q8no" value="No" required>
+ </fieldset>
+ <h4>IX</h4>
+ <fieldset id="q9">
+ <p>{{.q9}}</p>
+ <label for="q9yes">{{.yes}}</label>
+ <input type="radio" name="q9" id="q9yes" value="Yes" required>
+ <label for="q9no">{{.no}}</label>
+ <input type ="radio" name="q9" id="q9no" value="No" required>
+ </fieldset>
+ <h4>X</h4>
+ <fieldset id="q10">
+ <p>{{.q10}}</p>
+ <label for="q10yes">{{.yes}}</label>
+ <input type="radio" name="q10" id="q10yes" value="Yes" required>
+ <label for="q10no">{{.no}}</label>
+ <input type ="radio" name="q10" id="q10no" value="No" required>
+ </fieldset>
+ <h4>XI</h4>
+ <fieldset id="q11">
+ <p>{{.q11}}</p>
+ <label for="q11yes">{{.yes}}</label>
+ <input type="radio" name="q11" id="q11yes" value="Yes" required>
+ <label for="q11no">{{.no}}</label>
+ <input type ="radio" name="q11" id="q11no" value="No" required>
+ </fieldset>
+ <h4>{{.confirm}}</h4>
+ <fieldset id="q12">
+ <p>{{.q12}}</p>
+ <label for="confirm">{{.confirm}}</label>
+ <input type="checkbox" name="redFlag" id="confirm" required>
+ <br><!-- clean up the formatting on some browsers -->
+ </fieldset>
+ <h4>{{.user}}</h4>
+ <fieldset>
+ <label for="email">{{.email}}</label>
+ <input type="email" id="email" name="email" required>
+ <label for="name">{{.fullname}}</label>
+ <input id="name" name="name" required>
+ <input type="hidden" name="token" value="{{.token}}">
+ </fieldset>
+ <button type="submit">{{.submit}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/doctor/bookings.tpl
@@ -1,0 +1,7 @@
+{{define "content"}}
+ <main>
+ <!-- TODO: We need a calendar element expressed via a table with all upcoming appointments -->
+ <h2>YOU CURRENTLY HAVE NO APPOINTMENTS BOOKED</h2>
+ <p>If you have agreed to see a patient but do not see them on this page, please refer to the <a href="help.html">Help</a> section.</a>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/doctor/findpatients.tpl
@@ -1,0 +1,13 @@
+{{define "content"}}
+ <main>
+
+ <h2>{{.mainHeader}}</h2>
+ </main>
+ <!-- List patients seeking your specialty
+ who are in countries you are able to operate in
+ and output them here. This will require some
+ more data types included in router/pages.go
+ when finally implemented
+ -->
+
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/doctor/profile.tpl
@@ -1,0 +1,27 @@
+{{define "content"}}
+ <main>
+ <h2>{{.greetingHeader}}{{.username}}</h2>
+ <form method=POST>
+ <legend for="dates">{{.appLegend}}</legend>
+ <fieldset id="dates">
+ <!-- TODO: review better ways to set up chunks of availability
+ set up a recurring chunk for a range of hours with weekday checkboxes
+ then create a method for editing single days
+ this should be flexible enough to get out of the way generally
+ but still facilitate granular control when necessary
+ -->
+ <label for="startDate">{{.from}}</label>
+ <input id="startDate" name="startDate" type="datetime-local" required>
+ <br>
+ <label for="endDate">{{.to}}</label>
+ <input id="startDate" name="startDate" type="datetime-local" required>
+ <p>{{.bcu}}</p>
+ <label for="BTCperU">BTC:</label>
+ <input id="BTCperU" id="BTCperU" type="number" min="0.0012" max="1.0" step="0.00001" required>
+ </fieldset>
+ <button>{{.create}}</button>
+ <input type="hidden" name="token" value="{{.token}}">
+ <input type="reset">
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/footer.tpl
@@ -1,0 +1,51 @@
+{{define "footer"}}
+ <footer>
+ <nav class="leftfooter">
+ <details open="true">
+ <summary>{{.howworks}}</summary>
+ <ul>
+ <li><a href="{{.basedir}}/help/faq.html">{{.faq}}</a></li>
+ <li><a href="{{.basedir}}/help/appointments.html">{{.appts}}</a></li>
+ <li><a href="{{.basedir}}/help/contacting.html">{{.proc}}</a></li>
+ <li><a href="{{.basedir}}/help/catalog.html">{{.catalog}}</a></li>
+ <li><a href="{{.basedir}}/help/paymentmethods.html">{{.payments}}</a></li>
+ <li><a href="{{.basedir}}/help/pricesandfees.html">{{.fees}}</a></li>
+ <li><a href="{{.basedir}}/help/verification.html">{{.verify}}</a></li>
+ </ul>
+ </details>
+
+ <details open="true">
+ <summary>{{.partHead}}</summary>
+ <ul>
+ <li><a href="{{.basedir}}/partner.html">{{.partner}}</a></li>
+ <li><a href="{{.basedir}}/help/provider.html">{{.provider}}</a></li>
+ </ul>
+ </details>
+ </nav>
+ <section class="branding">
+ <a href="{{.basedir}}/index.html"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380" width="100%"><path d="m360.296875 172.976562-170.632813-170.632812c-.734374-.742188-1.621093-1.328125-2.613281-1.734375-1.953125-.808594-4.152343-.808594-6.113281 0-.984375.40625-1.871094 1-2.609375 1.734375l-170.621094 170.632812-5.359375 5.359376c-3.128906 3.128906-3.128906 8.183593 0 11.3125l175.992188 175.992187c.734375.742187 1.621094 1.328125 2.605468 1.734375.976563.410156 2.015626.617188 3.058594.617188 1.039063 0 2.078125-.207032 3.054688-.617188.984375-.40625 1.871094-.992188 2.605468-1.734375l175.992188-175.992187c3.128906-3.128907 3.128906-8.183594 0-11.3125zm-184.292969 48.777344-151.089844-37.761718 151.089844-37.761719zm16-75.523437 151.085938 37.761719-151.085938 37.761718zm-16-16.476563-136.570312 34.125 136.570312-136.574218zm0 108.476563v102.449219l-136.570312-136.574219zm16 0 136.566406-34.125-136.566406 136.574219zm0-108.476563v-102.449218l136.566406 136.566406zm0 0"/></svg></a>
+ <h1>Olmax Medical</h1>
+ <banner>{{.banner}}</banner>
+ <small>{{.copy}}</small>
+ </section>
+ <nav class="rightfooter">
+ <details open="true">
+ <summary>{{.contact}}</summary>
+ <ul>
+ <li><a href="mailto:olmaxmedical@gmail.com">{{.email}}</a></li>
+ <li><a href="tel:1-555-555-5555">{{.phone}}</a></li>
+ </ul>
+ </details>
+ <details open="true">
+ <summary>{{.legal}}</summary>
+ <ul>
+ <li><a href="{{.basedir}}/help/legal.html">{{.legal}}</a></li>
+ <li><a href="{{.basedir}}/help/privacy.html">{{.privacy}}</a></li>
+ </ul>
+ </details>
+ </nav>
+ </footer>
+</body>
+
+</html>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/header.tpl
@@ -1,0 +1,29 @@
+{{define "header"}}
+<!DOCTYPE html>
+<html>
+<head>
+ <title>{{.title}}</title>
+ {{if .css}}
+ <link rel="stylesheet" text="text/css" href="{{.basedir}}/css/{{.css}}">
+ {{end}}
+ <link rel="icon" type="image/svg+xml" href="{{.basedir}}/favicon.svg">
+ <link rel="stylesheet" test="text/css" href="{{.basedir}}/css/default.css">
+
+</head>
+<body>
+ <header class="navbar">
+ <!-- This changes based on user login status-->
+ <nav>
+ <ul>
+ <li><a href="{{.basedir}}/index.html">{{.home}}</a></li>
+ {{if eq .status "true"}}
+ <li><a href="{{.basedir}}/profile.html">{{.profile}}</a></li>
+ <li><a href="{{.basedir}}/logout.html">{{.logout}}</a></li>
+ {{else}}
+ <li><a href="{{.basedir}}/signup.html">{{.signup}}</a></li>
+ <li><a href="{{.basedir}}/login.html">{{.login}}</a></li>
+ {{end}}
+ </ul>
+ </nav>
+ </header>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/appointments.tpl
@@ -1,0 +1,42 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.requestHeader}}</h2>
+ <h3>{{.statusHeader}}</h3>
+ <p>{{.statusBody}}</p>
+ <br>
+ <h3>{{.scheduleHeader}}</h3>
+ <p>{{.scheduleBody}}</p>
+ <br>
+ <h3>{{.expiresHeader}}</h3>
+ <p>{{.expiresBody}}</p>
+ <br>
+ <h3>{{.emailHeader}}</h3>
+ <p>{{.emailBody1}}</p>
+ <p>{{.emailBody2}}</p>
+ <p style="margin-right: 40px">{{.emailBody3}}</p>
+ <p style="margin-right: 40px">{{.emailBody4}}</p>
+ <p style="margin-right: 40px">{{.emailBody5}}</p>
+ <h4>{{.notifyHeader}}</h4>
+ <p>{{.notifyBody}}</p>
+ <p style="margin-right: 40px">{{.notifyBody1}}</p>
+ <p style="margin-right: 40px">{{.notifyBody2}}</p>
+ <p style="margin-right: 40px">{{.notifyBody3}}</p>
+ <br>
+ <h4>{{.inboxSearchHeader}}</h4>
+
+ <p>{{.inboxSearchBody}}</p>
+
+ <h4>{{.checkSpamHeader}}</h4>
+ <p>{{.checkSpamBody}}</p>
+
+ <p style="margin-right: 40px">{{.checkSpamBody1}}</p>
+ <p style="margin-right: 40px">{{.checkSpamBody2}}</p>
+
+ <p>{{.checkSpamAdd}}</p></br>
+ <h4>{{.deliveryHeader}}</h4>
+ <br>
+ <h4>{{.blockHeader}}</h4>
+ <p>{{.blockBody}} <a href="https://www.torproject.org">Tor</a></p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/catalog.tpl
@@ -1,0 +1,20 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}<h2>
+<table border="1" cellpadding="8" cellspacing="2">
+<tr bgcolor="gray">
+ <th colspan="2">Profile</th>
+ <th>Country</th><th>Specialty</th><th>Rate <i>BTC</i></th></th>
+ {{range .doctors}}
+ <tr valign="top">
+ <td><img src="../images/{{.Image}}" /><a href="invoice.html"><h4>{{.Name}}</h4></a></td>
+ <td><p>{{.AlmaMater}}</p>
+ <p>{{.Residency}}</p>
+ <p>{{.Current}}</p>
+ <td>{{.Country}}</td>
+ <td>{{.Specialty}}</td>
+ <td>{{.Rate}}</td>
+ {{end}}
+ </table>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/contacting.tpl
@@ -1,0 +1,19 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.contactHeader}}</h2>
+ <p>{{.contactBody}}</p>
+ <br>
+ <h4>{{.scheduleHeader}}</h4>
+ <p>{{.scheduleBody}}<p>
+ <br>
+ <h4>{{.chargedHeader}}</h4>
+ <p>{{.chargedBody}}</p>
+ <br>
+ <h4>{{.anycurrHeader}}</h4>
+ <p>{{.anycurrBody}}</p>
+ <br>
+ <h4>{{.blocksHeader}}</h4>
+ <p>{{.blocksBody}} <a href="https://www.torproject.org">Tor</a></p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/faq.tpl
@@ -1,0 +1,32 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.helpHeader}}</h2>
+ <h4>{{.topics}}</h4>
+ <h4>{{.appointmentHeader}}</h4>
+ <p>{{.appointmentStatus}}</p>
+ <p>{{.appointmentClear}}</p>
+ <p>{{.appointmentExpire}}</p>
+ <a href="appointments.html">{{.viewall}}</a>
+ <h4>{{.paymentHeader}}</h4>
+ <p>{{.paymentEdit}}</p>
+ <p>{{.paymentBitcoin}}</p>
+ <p>{{.paymentBitcoinHow}}</p>
+ <p>{{.paymentAdd}}</p>
+ <a href="paymentmethods.html">{{.viewall}}</a>
+ <h4>{{.verify}}</h4>
+ <p>{{.verifyPhone}}</p>
+ <p>{{.verifyEmail}}</p>
+ <p>{{.verifyLicense}}</p>
+ <a href="verification.html">{{.viewall}}</a>
+ <h4>{{.priceHeader}}</h4>
+ <p>{{.priceDetermined}}</p>
+ <p>{{.priceWhen}}</p>
+ <p>{{.priceCurrency}}</p>
+ <a href="pricesandfees.html">{{.viewall}}</a>
+ <h4>{{.contactHeader}}</h4>
+ <p>{{.contactStatus}}</p>
+ <p>{{.contactHow}}</p>
+ <a href="contacting.html">{{.viewall}}</a>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/paymentmethods.tpl
@@ -1,0 +1,28 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.paymentHeader}}</h2>
+ <p>{{.paymentBody}} <a href="https:/bitcoin.org">Bitcoin</a></p>
+ <h4>{{.whatBTCHeader}}</h4>
+ <p>{{.whatBTCBody}} <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a></p>
+ <br>
+ <h4>{{.chargedHeader}}</h4>
+ <p>{{.chargedBody}}</p>
+ <br>
+ <h4>{{.anyCoinHeader}}</h4>
+ <p>{{.anyCoinBody}}</p>
+ <br>
+ <h4>{{.editWalletHeader}}</h4>
+ <p>{{.editWalletBody}}</p>
+ <br>
+ <h4>{{.delWalletHeader}}</h4>
+ <p>{{.delWalletBody}}</p>
+ <p>{{.delWalletBody1}}</p>
+ <p>{{.delWalletBody2}}</p>
+ <br>
+<p>{{.otherCoinNote}}</p>
+ <br>
+ <h4>{{.blockedHeader}}</h4>
+<p>{{.blockedBody}}<a href="https://www.torproject.org">Tor</a></p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/pricesandfees.tpl
@@ -1,0 +1,19 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.priceHeader}}</h2>
+ <p>{{.priceBody}}</p>
+ <br>
+ <h4>{{.determineHeader}}</h4>
+ <p>{{.determineBody}}<p>
+ <br>
+ <h4>{{.chargedHeader}}</h4>
+ <p>{{.chargedBody}}</p>
+ <br>
+ <h4>{{.currencyHeader}}</h4>
+ <p>{{.currencyBody}}</p>
+ <br>
+ <h4>{{.blockHeader}}</h4>
+ <p>{{.blockBody}}<a href="https://www.torproject.org">Tor</a></p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/provider.tpl
@@ -1,0 +1,31 @@
+{{define "content"}}
+ <main>
+ <h2>{{.mainHeader}}</h2>
+ <h3>{{.earn}}</h3>
+ <form method="post">
+ {{template "specialty" .specialties}}
+ <button>{{.getStartedHeader}}</button>
+ </form>
+ <!--TODO change link from TODO.html-->
+ <a href="TODO.html">{{.getStartedLink}}</a>
+ <h3>{{.providerWhy}} </h3>
+ <p>{{.whyText}}</p>
+ <h3>{{.control}}</h3>
+ <p>{{.controlText}}</p>
+ <h3>{{.everyStep}}</h3>
+ <p>{{.everyStepText}}</p>
+ <h1><strong>{{.provider}}</strong></h1>
+ <h1><strong>1</strong></h1>
+ <h4>{{.createProfile}}</h4>
+ <p>{{.createProfileText}}</p>
+ <h1><strong>2</strong></h1>
+ <h4>{{.welcomePatient}}</h4>
+ <p>{{.welcomePatientText}}</p>
+ <h1><strong>3</strong></h1>
+ <h4>{{.getPaid}}</h4>
+ <p>{{.getPaidText}}</p>
+ <h1><strong>{{.safety}}</strong></h1>
+ <h3>{{.trust}}</h3>
+ <p>{{.trustText}}</p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/help/verification.tpl
@@ -1,0 +1,14 @@
+{{define "content"}}
+ <main>
+ <h1>{{.mainHeader}}</h1>
+ <h2>{{.verifyHeader}}</h2>
+ <p>{{.verifyBody}}</p>
+ <h4>{{.phoneHeader}}</h4>
+ <p>{{.phoneBody}}</p>
+ <h4>{{.noNoteHeader}}</h4>
+ <p>{{.noNoteBody}}<a href="{{.basedir}}/appointmentRequests.html">Appointment Requests</a></p>
+
+ <h4>{{.blockHeader}}</h4>
+ <p>{{.blockBody}}<a href="https://www.torproject.org">Tor</a></p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/index.tpl
@@ -1,0 +1,24 @@
+{{define "content"}}
+ <main>
+ <section>
+ <h2>{{.whoWeAre}}</h2>
+ <p>{{.aboutUs}}</p>
+ </section>
+ <section>
+ <h2>{{.secondOpinions}}</h2>
+ <p>{{.fromHome}}</p>
+ </section>
+ <section>
+ <h2>{{.anonymity}}</h2>
+ <p>{{.anonText}}</p>
+ </section>
+ <section>
+ <h2>{{.wholeWorld}}</h2>
+ <p>{{.wholeWorldText}}</p>
+ </section>
+ <section>
+ <h2>{{.payment}}</h2>
+ <p>{{.paymentText}}</p>
+ </section>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/layout.tpl
@@ -1,0 +1,7 @@
+{{define "layout"}}
+{{template "header" .header}}
+ <div class="content">
+{{template "content" .}}
+ </div>
+{{template "footer" .footer}}
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/login.tpl
@@ -1,0 +1,14 @@
+{{define "content"}}
+ <main>
+ <h3>{{if .redirect }}{{.continue}}{{else}}{{.greeting}}{{end}}</h3>
+ {{template "errors" .errors}}
+ <form method="post" action="login.html">
+ <label for="email">{{.email}}*</label>
+ <input type="email" name="email" id="email" required autocomplete="off"/><br>
+ <label for="pass">{{.password}}*</label>
+ <input type="password" name="pass" id="pass" minlength="8" required autocomplete="off"/><br>
+ <p class="forgot"><a href="resetpassword.html">{{.forgotPassword}}</a></p>
+ <button type="submit" class="button button-block"/>{{.login}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/messages.tpl
@@ -1,0 +1,6 @@
+{{define "content"}}
+ <main>
+ <h2>{{.mainHeader}}</h2>
+ <p>{{.messages}}</p>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/newpassword.tpl
@@ -1,0 +1,15 @@
+{{define "content"}}
+ <main>
+ <h3>{{.reset}}</h3>
+
+ {{template "errors" .errors}}
+ <form method="post" action="{{.basedir}}/newpassword.html">
+ <input type="hidden" name="token" value="{{.token}}"/>
+ <label for="password">{{.password}}*</label>
+ <input type="password" name="password" id="password" required autocomplete="off"/><br>
+ <laber for="reenter">{{.reenter}}*</label>
+ <input type="password" name="reenter" id="reenter" required autocomplete="off"/><br>
+ <button type="submit" class="button button-block"/>{{.update}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/patient/appointments.tpl
@@ -1,0 +1,7 @@
+{{define "content"}}
+ <main>
+ <!-- TODO: List each upcoming appointment, one per row as <details> -->
+ <h2>{{.mainHeader}}</h2>
+ <p>{{.mainBody}}</a>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/patient/offer.tpl
@@ -1,0 +1,18 @@
+{{define "content"}}
+ <main>
+ <h2>{{.mainHeader}}</h2>
+ <form action="findspecialty">
+ {{template "specialty" .specialties}}
+ <br/>
+ <label for="Amount">{{.bcu}} <i>({{.rate}})</i></label>
+ <input type="text" name="Amount" size="15" maxlength="10" />
+ <h3>{{.dates}}</h3>
+ <label for="startDate">{{.from}}</label>
+ <input id="startDate" type="date" name="startDate" required>
+ <label for="endDate">{{.to}}</label>
+ <input id="endDate" type="date" name="endDate" required>
+ <br/>
+ <button>{{.deploy}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/patient/profile.tpl
@@ -1,0 +1,8 @@
+{{define "content"}}
+ <main>
+ <h2>{{.greetingHeader}}{{.username}}</h2>
+ <fieldset id="find-dr">
+ <!-- list appointments here -->
+ </fieldset>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/patient/symptoms.tpl
@@ -1,0 +1,58 @@
+{{define "content"}}
+ <!-- This will be emailed directly to the physician on completion
+ it is locally validated, but never locally stored
+ -->
+ <main>
+ <h2>{{.createHeader}}</h2>
+ <hr/>
+ <h2>{{.formHeader}}</h2>
+ <form action="post">
+ <label for="bday">{{.birthdate}}</label>
+ <input type="date" name="bday"/>
+ <label for="gender">{{.gender}}</label>
+ <input type="radio" name="gender" value="male"/>{{.male}}
+ <input type ="radio" name="gender" value="female"/>{{.female}}
+ <label for="reason">{{.visitReason}}</label>
+ <textarea name="reason" row="6" cols="50"></textarea>
+ <label for="onset">{{.symptomStart}}</label>
+ <input type="date" name="onset"/>
+ <label for="location">{{.symptomArea}}</label>
+ <input type="text" id="location"/>
+ <laber for="duration">{{.symptomDuration}}</label>
+ <input type="number" min="0" id="duration"/>
+ <label for="characteristic">{{.symptomDescription}}</label>
+ <input type="text" id="characteristic"/>
+ <label for="aggreAlevi">{{.symptomAugment}}</label>
+ <input type="text" id="aggreAlevi"/>
+ <label for="radiate">{{.symptomProliferation}}</label>
+ <input type="text" id="radiate"/>
+ <label for="treatments">{{.symptomTreatment}}</label>
+ <textarea name="treatments" row="6" cols="50"></textarea>
+ <fieldset>
+ <legend>{{.legend}}</legend>
+ <!--"ros" means Review of Systems -->
+ <input type="radio" name="ros" id="feversChills" value="feversChills" />
+ <label for="feversChills">{{.feversChills}}</label><br />
+ <input type="radio" name="ros" id="wtGainLoss" value="wtGainLoss" />
+ <label for="wtGainLoss">{{.wtGainLoss}}</label><br />
+ <input type="radio" name="ros" id="vison" value="vision" />
+ <label for="vision">{{.vision}}</label><br />
+ <input type="radio" name="ros" id="lung" value="lung" />
+ <label for="lung">{{.lung}}</label><br />
+ <input type="radio" name="ros" id="heart" value="heart" />
+ <label for="heart">{{.heart}}</label><br />
+ <input type="radio" name="ros" id="bowel" value="bowel" />
+ <label for="bowel">{{.bowel}}</label><br />
+ <input type="radio" name="ros" id="renal" value="renal" />
+ <label for="renal">{{.renal}}</label><br />
+ <input type="radio" name="ros" id="musSkel" value="musSkel" />
+ <label for="musSkel">{{.musSkel}}</label><br />
+ <input type="radio" name="ros" id="neuro" value="neuro" />
+ <label for="neuro">{{.neuro}}</label><br />
+ <input type="radio" name="ros" id="psych" value="psych">
+ <label for="psych">{{.psych}}<br/>
+ </fieldset>
+ <input type="submit" value="submit">
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/appointments.go
@@ -1,0 +1,25 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/router"
+)
+
+// AddAppointment registers an appointment into the appointment book
+// TODO(halfwit) message/email client to fill out Symptoms form
+const AddAppointment router.PluginMask = 1 << 1
+
+func init() {
+ b := &router.Plugin{
+ Name: "Add Appointments",
+ Run: nil,
+ Validate: addAppt,
+ }
+ router.AddPlugin(b, AddAppointment)
+}
+
+func addAppt(s *router.Request) error {
+ // get &id=
+ // Auth user and requisite key
+ // TODO(halfwit) create unique key in patient/appointments
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/appointments.tpl
@@ -1,0 +1,3 @@
+{{define "appointments"}}
+<!-- appointments here -->
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/bookings.go
@@ -1,0 +1,22 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/router"
+)
+
+// ListBookings retreives a list of all upcoming bookings for a given doctor
+const ListBookings router.PluginMask = 1 << 2
+
+func init() {
+ b := &router.Plugin{
+ Name: "List Bookings",
+ Run: nil,
+ Validate: listBookings,
+ }
+ router.AddPlugin(b, ListBookings)
+}
+
+func listBookings(s *router.Request) error {
+
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/bookings.tpl
@@ -1,0 +1,3 @@
+{{define "bookings"}}
+<!-- bookings form here -->
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/countries.go
@@ -1,0 +1,96 @@
+package plugins
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/olmaxmedical/router"
+ "github.com/pariz/gountries"
+ "golang.org/x/text/message"
+)
+
+// Countries - Populate a localized spinner to select country
+const Countries router.PluginMask = 1 << 3
+
+// Country - Mapping token to internationalized country code
+type Country struct {
+ ID string
+ Name string
+}
+
+type countries struct {
+ list []gountries.Country
+}
+
+var cache *countries
+
+func init() {
+ var l []gountries.Country
+ c := gountries.New()
+ for _, c := range c.FindAllCountries() {
+ l = append(l, c)
+ }
+ cache = &countries{
+ list: l,
+ }
+ sort.Sort(cache)
+ b := &router.Plugin{
+ Name: "country",
+ Run: listCountries,
+ Validate: validateCountries,
+ }
+ router.AddPlugin(b, Countries)
+}
+
+// Len - For Sort implementation
+func (c *countries) Len() int {
+ return len(c.list)
+}
+
+// Less - For Sort implementation
+func (c *countries) Less(i, j int) bool {
+ switch strings.Compare(c.list[i].Name.Common, c.list[j].Name.Common) {
+ case -1:
+ return true
+ default:
+ return false
+ }
+}
+
+// Swap - For Sort implementation
+func (c *countries) Swap(i, j int) {
+ tmp := c.list[i]
+ c.list[i] = c.list[j]
+ c.list[j] = tmp
+}
+
+func listCountries(r *router.Request) map[string]interface{} {
+ p := r.Printer()
+ // TODO(halfwit): Use Request to get a localized country name
+ c := make(map[string]interface{})
+ c["label"] = p.Sprint("Select country/countries")
+ for _, item := range cache.list {
+ c[item.Name.Common] = item.Name.Common
+ }
+ return c
+}
+
+func validateCountries(r *router.Request) error {
+ s := r.Request()
+ for _, c := range s.PostFormValue("country") {
+ if msg := checkCountry(r.Printer(), c); msg != nil {
+ return msg
+ }
+ }
+ return nil
+}
+
+func checkCountry(p *message.Printer, country rune) error {
+ for _, item := range cache.list {
+ if item.Name.Common == string(country) {
+ return nil
+ }
+ }
+ return fmt.Errorf("%s", p.Sprint("No country entered/nil value entered"))
+}
--- /dev/null
+++ b/templates/plugins/countries.tpl
@@ -1,0 +1,8 @@
+{{define "country"}}
+<label for="country">{{.label}}</label>
+<select name="country" id="country" multiple required>
+ {{range $id, $name := .}}
+ <option value="{{$id}}">{{$name}}</option>
+ {{end}}
+</select>
+{{end}}
--- /dev/null
+++ b/templates/plugins/doctor.go
@@ -1,0 +1,55 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/router"
+)
+
+// ListDoctors - Bitmask to list doctors of in client country
+const ListDoctors router.PluginMask = 1 << 4
+
+type doctor struct {
+ Image string
+ AlmaMater string
+ Name string
+ Residency string
+ Current string
+ Country string
+ Specialty string
+ Rate string
+}
+
+func init() {
+ b := &router.Plugin{
+ Name: "doctors",
+ Run: ListDocs,
+ Validate: nil,
+ }
+ router.AddPlugin(b, ListDoctors)
+}
+
+// ListDocs - Query db and return list of doctors in country
+// These may need eventual localization for any bilingual doctors we have
+func ListDocs(r *router.Request) map[string]interface{} {
+ return map[string]interface{}{
+ "Mark Abuzamzam, MD": &doctor{
+ Image: "AbuzamzamMD.jpg",
+ AlmaMater: "University of Southern California School of Medicine",
+ Residency: "University of Southern California, San Diego. Internal Medicine Residency",
+ Name: "Mark Abuzamzam, MD",
+ Current: "Current Faculty at University of California Irvine Program Director",
+ Country: "United States of America",
+ Specialty: "Internal Medicine and Addictions Medicine",
+ Rate: "0.0013 BTC",
+ },
+ "Martha Woodfin, MD": &doctor{
+ Image: "WoodfinMD.jpg",
+ Name: "Martha Woodfin, MD",
+ AlmaMater: "University Seoul School of Medicine",
+ Residency: "University of Las Vegas Nevada, Pediatric Medicine Residency",
+ Current: "Current Staff at Mercy Hospital Jackson NC",
+ Country: "United States of America",
+ Specialty: "Internal Medicine",
+ Rate: "0.0011 BTC",
+ },
+ }
+}
--- /dev/null
+++ b/templates/plugins/email.go
@@ -1,0 +1,83 @@
+package plugins
+
+import (
+ "errors"
+ "log"
+ "mime/multipart"
+
+ "github.com/olmaxmedical/email"
+ "github.com/olmaxmedical/router"
+)
+
+// EmailForm - Patient form to gmail
+const EmailForm router.PluginMask = 1 << 5
+
+// SendSignup - Send account creation validation email
+const SendSignup router.PluginMask = 1 << 6
+
+// SendReset - Send password reset email
+const SendReset router.PluginMask = 1 << 7
+
+func init() {
+ b := &router.Plugin{
+ Name: "emailform",
+ Run: nil,
+ Validate: emailForm,
+ }
+ router.AddPlugin(b, EmailForm)
+ c := &router.Plugin{
+ Name: "signupEmail",
+ Run: nil,
+ Validate: signupEmail,
+ }
+ router.AddPlugin(c, SendSignup)
+ d := &router.Plugin{
+ Name: "resetPassword",
+ Run: nil,
+ Validate: resetPassword,
+ }
+ router.AddPlugin(d, SendReset)
+}
+
+func signupEmail(s *router.Request) error {
+ r := s.Request()
+ first := r.PostFormValue("fname")
+ last := r.PostFormValue("lname")
+ address := r.PostFormValue("email")
+ pass := r.PostFormValue("pass")
+ email.SendSignup(first, last, address, pass, s.Printer())
+ return nil
+}
+
+func resetPassword(s *router.Request) error {
+ p := s.Printer()
+ r := s.Request()
+ email.SendReset(r.PostFormValue("email"), p)
+ return nil
+}
+
+func emailForm(s *router.Request) error {
+ p := s.Printer()
+ r := s.Request()
+ r.ParseMultipartForm(10 << 20) // parse up to 10MB
+ if r.PostFormValue("name") == "" || r.PostFormValue("email") == "" {
+ return errors.New(p.Sprint("Missing name or email in form. Please contact us at olmaxmedical@gmail.com"))
+ }
+ if b, ok := r.Form["sendto"]; !ok || b[0] == "" {
+ return errors.New(p.Sprint("Missing value for target email. Please contact us at olmaxmedical.gmail.com"))
+ }
+ attachments := make(map[string]multipart.File)
+ m := r.MultipartForm
+ for _, headers := range m.File {
+ for _, header := range headers {
+ file, err := header.Open()
+ if err != nil { //non fatal, log any oddities and continue
+ log.Println(err)
+ continue
+ }
+ attachments[header.Filename] = file
+ }
+ }
+ email.SendForm(r.Form, p, attachments)
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/errors.go
@@ -1,0 +1,28 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/router"
+)
+
+// FormErrors - A list of errors present on a POST request
+const FormErrors router.PluginMask = 1 << 8
+
+func init() {
+ b := &router.Plugin{
+ Name: "errors",
+ Run: GetFormErrors,
+ Validate: nil,
+ }
+ router.AddPlugin(b, FormErrors)
+}
+
+// GetFormErrors - return the client a list of any errors in the form
+func GetFormErrors(r *router.Request) map[string]interface{} {
+ s := r.Session()
+ if s == nil {
+ return nil
+ }
+ return map[string]interface{}{
+ "errors": s.Get("errors"),
+ }
+}
--- /dev/null
+++ b/templates/plugins/errors.tpl
@@ -1,0 +1,5 @@
+{{define "errors"}}
+{{range .}}
+<p style="color: red" class="errtext">{{.}}</p>
+{{end}}
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/messages.go
@@ -1,0 +1,29 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/router"
+)
+
+// Messages - list all messages by key for use in a message template
+const Messages router.PluginMask = 1 << 9
+
+func init() {
+ b := &router.Plugin{
+ Name: "messages",
+ Run: GetMessages,
+ Validate: nil,
+ }
+ router.AddPlugin(b, Messages)
+}
+
+// GetMessages - return a map of message structs
+func GetMessages(r *router.Request) map[string]interface{} {
+ s := r.Session()
+ if s == nil {
+ return nil
+ }
+ return map[string]interface{}{
+ // No, this won't actually do anything.
+ "messages": s.Get("messages"),
+ }
+}
--- /dev/null
+++ b/templates/plugins/offers.go
@@ -1,0 +1,19 @@
+package plugins
+
+import "github.com/olmaxmedical/router"
+
+// MakeOffer - Request a time slot with doctor
+const MakeOffer router.PluginMask = 1 << 10
+
+func init() {
+ b := &router.Plugin{
+ Name: "offer",
+ Run: nil,
+ Validate: offer,
+ }
+ router.AddPlugin(b, MakeOffer)
+}
+
+func offer(s *router.Request) error {
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/password.go
@@ -1,0 +1,62 @@
+package plugins
+
+import (
+ "errors"
+
+ "github.com/olmaxmedical/database"
+ "github.com/olmaxmedical/router"
+)
+
+// ValidateLogin - Check user/pass combo exists
+const ValidateLogin router.PluginMask = 1 << 11
+
+// ResetPassword - Update database entry for password
+const ResetPassword router.PluginMask = 1 << 12
+
+func init() {
+ b := &router.Plugin{
+ Name: "login",
+ Run: nil,
+ Validate: login,
+ }
+ router.AddPlugin(b, ValidateLogin)
+ c := &router.Plugin{
+ Name: "setPassword",
+ Run: nil,
+ Validate: setPass,
+ }
+ router.AddPlugin(c, ResetPassword)
+}
+
+func login(s *router.Request) error {
+ r := s.Request()
+ us := s.Session()
+ p := s.Printer()
+ user := r.PostFormValue("email")
+ pass := r.PostFormValue("pass")
+ if database.ValidateLogin(user, pass) {
+ us.Set("username", user)
+ us.Set("login", "true")
+ us.Set("role", database.UserRole(user))
+ us.Set("token", database.NewToken())
+ return nil
+ }
+ return errors.New(p.Sprint("Invalid login"))
+}
+
+func setPass(s *router.Request) error {
+ r := s.Request()
+ p := s.Printer()
+
+ pass := r.PostFormValue("password")
+ repeat := r.PostFormValue("reenter")
+ if pass != repeat {
+ return errors.New(p.Sprint("Passwords do not match"))
+ }
+ token := r.PostFormValue("token")
+ if !database.FindTempEntry(token) {
+ return errors.New(p.Sprint("Session expired"))
+ }
+ database.UpdateUserPassword(token, pass)
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/search.go
@@ -1,0 +1,20 @@
+package plugins
+
+import "github.com/olmaxmedical/router"
+
+// Search - generic search for doctors in area
+const Search router.PluginMask = 1 << 13
+
+func init() {
+ b := &router.Plugin{
+ Name: "search",
+ Run: nil,
+ Validate: search,
+ }
+ router.AddPlugin(b, Search)
+}
+
+// Stuuuuubbb
+func search(r *router.Request) error {
+ return nil
+}
--- /dev/null
+++ b/templates/plugins/search.tpl
@@ -1,0 +1,3 @@
+{{define "search"}}
+<!-- Search bar here -->
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/services.go
@@ -1,0 +1,114 @@
+package plugins
+
+import (
+ "fmt"
+
+ "github.com/olmaxmedical/router"
+)
+
+// Services - Bitmask to list services in native language
+const Services router.PluginMask = 1 << 14
+
+func init() {
+ b := &router.Plugin{
+ Name: "specialties",
+ Run: ListServices,
+ Validate: ValidateServices,
+ }
+ router.AddPlugin(b, Services)
+}
+
+// ValidateServices - Ensure the specialties entered exist in our map
+func ValidateServices(r *router.Request) error {
+ s := r.Request()
+ var errs []string
+ for _, entry := range s.PostFormValue("specialty") {
+ switch string(entry) {
+ case "acutepain":
+ case "anasthesiology":
+ case "bariatric":
+ case "cardiology":
+ case "chiropractic":
+ case "chronic":
+ case "critcare":
+ case "dermatology":
+ case "emergency":
+ case "endocrinology":
+ case "otolaringology":
+ case "familymedicine":
+ case "gastro":
+ case "headneck":
+ case "hematology":
+ case "hepatology":
+ case "hyperbaric":
+ case "immunology":
+ case "diseases":
+ case "internal":
+ case "neonatal":
+ case "nephrology":
+ case "neurology":
+ case "neurosurgery":
+ case "obstetrics":
+ case "occupational":
+ case "opthamology":
+ case "orthopedics":
+ case "palliative":
+ case "pediatrics":
+ case "podiatry":
+ case "pulmonology":
+ case "radiology":
+ case "radiation":
+ case "transplants":
+ continue
+ default:
+ errs = append(errs, fmt.Sprintf("Unknown entry: %q\n", entry))
+ }
+ if len(errs) > 0 {
+ return fmt.Errorf("%s", errs)
+ }
+ }
+ return nil
+}
+
+// ListServices - return a list of native language representations of our medical fields
+func ListServices(r *router.Request) map[string]interface{} {
+ p := r.Printer()
+ return map[string]interface{}{
+ "label": p.Sprint("Select specialty/specialties"),
+ "acutepain": p.Sprint("Acute Pain Medicine"),
+ "anesthesiology": p.Sprint("Anesthesiology"),
+ "bariatric": p.Sprint("Bariatric Surgery"),
+ "cardiology": p.Sprint("Cardiology"),
+ "chiropractic": p.Sprint("Chiropractics"),
+ "chronic": p.Sprint("Chronic Pain"),
+ "critcare": p.Sprint("Critical Care"),
+ "dermatology": p.Sprint("Dermatology"),
+ "emergency": p.Sprint("Emergency Medicine"),
+ "endocrinology": p.Sprint("Endocrinology"),
+ "otolaringology": p.Sprint("Ear Nose and Throat"),
+ "familymedicine": p.Sprint("Family Medicine"),
+ "gastro": p.Sprint("Gastrointestinology"),
+ "headneck": p.Sprint("Head and Neck"),
+ "hematology": p.Sprint("Hematology and Oncology"),
+ "hepatology": p.Sprint("Hepatology"),
+ "hyperbaric": p.Sprint("Hyperbaric"),
+ "immunology": p.Sprint("Immunology"),
+ "diseases": p.Sprint("Infectious Diseases"),
+ "internal": p.Sprint("Internal Medicine"),
+ "neonatal": p.Sprint("Neonatology"),
+ "nephrology": p.Sprint("Nephrology"),
+ "neurology": p.Sprint("Neurology"),
+ "neurosurgery": p.Sprint("Neurosurgery"),
+ "obstetrics": p.Sprint("Obstetrics and Gynecology"),
+ "occupational": p.Sprint("Occupational Medicine"),
+ "opthamology": p.Sprint("Opthamology"),
+ "orthopedics": p.Sprint("Orthopedic Surgery"),
+ "palliative": p.Sprint("Palliative Care"),
+ "pediatrics": p.Sprint("Pediatrics"),
+ "podiatry": p.Sprint("Podiatry"),
+ "pulmonology": p.Sprint("Pulmonology"),
+ "radiology": p.Sprint("Radiology"),
+ "radiation": p.Sprint("Radiaton Oncology"),
+ "transplants": p.Sprint("Transplant Surgery"),
+ }
+}
--- /dev/null
+++ b/templates/plugins/specialties.tpl
@@ -1,0 +1,8 @@
+{{define "specialty"}}
+<label for="Specialty">{{.label}}</label>
+<select name="Specialty" id="specialty" multiple required>
+ {{range $id, $name := .}}
+ <option value="{{$id}}">{{$name}}</option>
+ {{end}}
+</select>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/plugins/tokens.go
@@ -1,0 +1,29 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/database"
+ "github.com/olmaxmedical/router"
+)
+
+// FormToken - A database-persisted one time use token to relate forms to POST requests
+const FormToken router.PluginMask = 1 << 15
+
+func init() {
+ c := &router.Plugin{
+ Name: "formToken",
+ Run: newFormToken,
+ Validate: validateToken,
+ }
+ router.AddPlugin(c, FormToken)
+}
+
+func validateToken(r *router.Request) error {
+ return database.ValidateToken(r.Request(), r.Session())
+}
+
+// TODO(halfwit) - database
+func newFormToken(r *router.Request) map[string]interface{} {
+ return map[string]interface{}{
+ "token": database.NewToken(),
+ }
+}
--- /dev/null
+++ b/templates/resetpassword.tpl
@@ -1,0 +1,12 @@
+{{define "content"}}
+ <main>
+ <h3>{{.reset}}</h3>
+ {{template "errors" .errors}}
+ <p>{{.resettext}}
+ <form method="post" action="resetpassword.html">
+ <label for="email">{{.email}}*</label>
+ <input type="email" name="email" id="email" required autocomplete="off"/><br>
+ <button type="submit" class="button button-block"/>{{.sendreset}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/signup.tpl
@@ -1,0 +1,17 @@
+{{define "content"}}
+ <main>
+ <h2>{{.mainHeader}}</h2>
+ {{template "errors" .errors}}
+ <form method="post" action="signup.html">
+ <label for="fname">{{.fname}}*</label>
+ <input type="text" name="fname" id="fname" placeholder="{{.fnameph}}" required autocomplete="off" autofocus/><br>
+ <label for="lname">{{.lname}}*</label>
+ <input type="text" name="lname" id="lname" placeholder="{{.lnameph}}" required autocomplete="off"/><br>
+ <label for="email">{{.email}}*</label>
+ <input type="email" name="email" id="email" placeholder="{{.emailph}}" required autocomplete="off"/><br>
+ <label for="pass">{{.pass}}*</label>
+ <input type="password" name="pass" id="pass" minlength="8" placeholder="{{.passph}}" required autocomplete="off"/><br>
+ <button type="submit" class="button button-block"/>{{.gobutton}}</button>
+ </form>
+ </main>
+{{end}}
\ No newline at end of file
--- /dev/null
+++ b/templates/template_test.go
@@ -1,0 +1,28 @@
+package template
+
+import (
+ "testing"
+ "text/template"
+)
+
+func TestTemplates(t *testing.T) {
+ if _, e := template.ParseGlob("*.tpl"); e != nil {
+ t.Error(e)
+ }
+
+ if _, e := template.ParseGlob("help/*.tpl"); e != nil {
+ t.Error(e)
+ }
+
+ if _, e := template.ParseGlob("doctor/*.tpl"); e != nil {
+ t.Error(e)
+ }
+
+ if _, e := template.ParseGlob("patient/*.tpl"); e != nil {
+ t.Error(e)
+ }
+
+ if _, e := template.ParseGlob("plugins/*.tpl"); e != nil {
+ t.Error(e)
+ }
+}
--- /dev/null
+++ b/templates/wallet.tpl
@@ -1,0 +1,16 @@
+{{define "content"}}
+ <main>
+ <h2>{{.mainHeader}}</h2>
+ <div align="center">
+ <h1>{{.funds}}</h1>
+ <p>{{.current}}</p>
+ </hr>
+ </div>
+ <div align="center">
+ <h2>{{.deposit}}</h2>
+ <img src="../images/bitcoinRQ.jpg" alt="[redacted]" width="155" height="155"/>
+ <h3>[redacted]</h3>
+ <h4>{{.onlyHeader}}</h4>
+ <p>{{.onlyBody}}</p>
+ </main>
+{{end}}
--- a/wallet.tpl
+++ /dev/null
@@ -1,16 +1,0 @@
-{{define "content"}}
- <main>
- <h2>{{.mainHeader}}</h2>
- <div align="center">
- <h1>{{.funds}}</h1>
- <p>{{.current}}</p>
- </hr>
- </div>
- <div align="center">
- <h2>{{.deposit}}</h2>
- <img src="../images/bitcoinRQ.jpg" alt="[redacted]" width="155" height="155"/>
- <h3>[redacted]</h3>
- <h4>{{.onlyHeader}}</h4>
- <p>{{.onlyBody}}</p>
- </main>
-{{end}}