From 295f9e9700b392e2f92b214bab0d8478e60b0e3a Mon Sep 17 00:00:00 2001 From: Bryan Cerrati Date: Fri, 1 Nov 2024 13:08:24 -0400 Subject: [PATCH] Upload --- .DS_Store | Bin 0 -> 8196 bytes Dockerfile | 20 ++++ __pycache__/forms.cpython-38.pyc | Bin 0 -> 2070 bytes __pycache__/models.cpython-38.pyc | Bin 0 -> 1833 bytes __pycache__/routes.cpython-38.pyc | Bin 0 -> 6387 bytes app.py | 44 +++++++++ docker-compose.yml | 10 ++ forms.py | 36 +++++++ instance/.DS_Store | Bin 0 -> 6148 bytes models.py | 35 +++++++ requirements.txt | 3 + routes.py | 151 ++++++++++++++++++++++++++++++ static/styles.css | 30 ++++++ templates/add_note.html | 12 +++ templates/add_onsite.html | 23 +++++ templates/add_ticket.html | 31 ++++++ templates/all_tickets.html | 85 +++++++++++++++++ templates/base.html | 21 +++++ templates/companies.html | 18 ++++ templates/index.html | 68 ++++++++++++++ templates/overview.html | 55 +++++++++++ templates/v2_index.html | 85 +++++++++++++++++ 22 files changed, 727 insertions(+) create mode 100644 .DS_Store create mode 100644 Dockerfile create mode 100644 __pycache__/forms.cpython-38.pyc create mode 100644 __pycache__/models.cpython-38.pyc create mode 100644 __pycache__/routes.cpython-38.pyc create mode 100644 app.py create mode 100644 docker-compose.yml create mode 100644 forms.py create mode 100644 instance/.DS_Store create mode 100644 models.py create mode 100644 requirements.txt create mode 100644 routes.py create mode 100644 static/styles.css create mode 100644 templates/add_note.html create mode 100644 templates/add_onsite.html create mode 100644 templates/add_ticket.html create mode 100644 templates/all_tickets.html create mode 100644 templates/base.html create mode 100644 templates/companies.html create mode 100644 templates/index.html create mode 100644 templates/overview.html create mode 100644 templates/v2_index.html diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a4a81994440f6843ec5644b6b5d7d4c75b34ce7e GIT binary patch literal 8196 zcmeHMOKTHR6h1fUV`5Q4QLLaa;6|jaO|%qsGo}#~Tp3aDL7K<39Xc~NCKIESLN+3z z3x9!sL0#(7g$wuk8~h96LcjZHJCjT*E=q;oTkbtK_kQQxbG|v5$(a%nD|MR%q8TEx z(1pxTVMu9WU-Y4t(JQAR8T5%7R6}1Um#RZ(vtSr73>XFs1BL;^!2iGip4p;VBcA(e z*Nlb%!@!|rK-?c}bRiur`%21N2L@RJK#pNqHq226NF7^CN6WsFQWZ8;^}w_$(e#mh9MaLUucT5Zrqqe)lbNnim^>YNwuBRNlr*DZz%Ve(fT-Q4P_0*~Mb8rTd-bNz z8+D)8fe>G+Yv^x(%ZAxVEq|?0Y4D&WF?6mt8X53%S=+bX7w>-xoiE~y5#9v6`48yU zdfW>~I5UBF6D|DBi%3&qn~%jdO-MQvC)D_6~*+T5HgTwE&7+LyOx?ae~5xHxMsE?(N&%2_AQ zUbuR@y5R>Q7eSygednj6>hsR{8Z!&@CWuI+VdjQ-N(^D*3HWP#?(2)HOu!V}ZtCrY zOC(*^77h;CdQxeJJ`dNhC*sNBQgbAmi{wbZDjc0exz%=2HeZ-&Flz#m+Zd}{yz literal 0 HcmV?d00001 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..672653b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use the official Python image from the Docker Hub +FROM python:3.8-slim + +# Set the working directory +WORKDIR /app + +# Copy the current directory contents into the container +COPY . /app + +# Ensure instance directory exists and is writable +RUN mkdir -p /app/instance && chmod -R 777 /app/instance + +# Install any needed packages specified in requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# Make port 5000 available to the world outside this container +EXPOSE 5005 + +# Run app.py when the container launches +CMD ["python", "app.py"] diff --git a/__pycache__/forms.cpython-38.pyc b/__pycache__/forms.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58393fcaeae5272efaf91af9fd08426978cab768 GIT binary patch literal 2070 zcmb_dPjBNy6rZsj+i~nPblGJ=0s;#xzGOLYtg2mYRZe6jTC|cSWVxP6>ePsWPBb%!Q z;4yr%1j0!|8A&W|Gs+#_x*%i9te1A;a*x?7?7XxRA8=~}w*k8wH~<>oaPIak5=Sy`~GsfAR|Fst|#6(NWu-ogB6 z0ufn8=5l{Hua3A#+=C`-<}$XF^K8baVhe-;xKGPkawd94y_X-?Mb4$xrCiVjF&oBR z<)`TsUP)6Gq-j;Nd5L_Orl<3)G$+Ca9m+1Ijqs53auZU4b)*~=Ql2!{si@JerBiL4 za;3ITKp7GM`q?WYJ^-l6tLRZSn>`vqB;;VW5N$X>S&2UTbes0{?;h1BuO;!il0O0Q z+euud&`Mg|Wi|xgV-5trrTk&ta11@f7dX*{tKtrjVeE^y5!^*`4+$2DaoU-pESe_X zM{@0f;XcH@J`mI<(JUVf*E|1<(VbNpqutAJ1^QSY+Wuwd31j`$_8a^_gR~#wUF81T zjRzpI4d0C$xbvDDSPQu15s=%lUzNUTAe-6D!8w7AFGFY#nH>HV;?` znd-bCBg!Jyz4Vjt1#w7%b7D&c&!)04xzlYUaLg^Y_OeC49`&1J-ha;d2^Rm?^^|1` z@hO}G^bY4-BL2+a_H)jrX6K>V@ehyZLW_KEHr#yyUAPc2K=BrmkC0r~N=^Z;mkkVl z*m`mRq#+GGCl}VlI;ZE>&p26OoLrK|o;bg?ekXh60?sFH>M;VI*~44vEYN@nJ3w{! zfsDyH`L6dPJ*N`_A01i0Sf^0Ty7a(5t6(~>$PT^`cx9tLu{2e%Qx>wp#@)qM(W!Nb zMV1e5Vme6EVp=q5I@l@eJS*icFzZ{fuUc|G<3iwl92-VfCqlJO=Ugn5ot33|9_uHz zl_PmMQcfnuQn@E*`1cA1eVXPl>Sda4G!Mq@(ygz9-|%)tgswpWLPn~`s3jSF*_m(tWYPDDLN k!~^8eqK)Kgdv%8W9W%Xmu`(qVYDn+XkcL*z?>Rl^AJ^c(b^rhX literal 0 HcmV?d00001 diff --git a/__pycache__/models.cpython-38.pyc b/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aec96f39771cf8e21652de829bcf93099d0a81d2 GIT binary patch literal 1833 zcmbVNOOM<{5O#a~8jojpc6Jj2h?fKj=8#C75n2dZgn&V?gB1B$o0+a^qo zgzH{8hvWVQeo9N6IPG7^iLct;VM79n;!&5ozpCyk*H_i^<8bI3cz*kHv&bF8_=^_T z9}9~^jA{wN4bCznXAxsGH#0LgBa<0|JvO4=mj>@~>sNzYqPMgj_aYmJ%^e_4hd4l7 z?g8;S#0AplJ`le{JU%!!!r&7AjF2h+`1@}@%jTyd-(cnOq!x9Wi#e&UKQ&CSjnwI4+W0#If?@I4^mV(L9LbvnI(pjmc-qxnE{YUMTmgq82AY zDl_HEIj&_|oG6P7RUk!{)M;5%r|CL!YaK-uxd7m-x-jG|#H_{BoqNf8eGmRbR^451 zBr%RkFe(qiV*SffD8Q&FT%!6GJJ|j}I_aMyooeF{qxuEn)ksHsS!lg2;md(0 z!~ta;wacN{S?&TQYy{f&xC=Sv9;ob}o7~6l{r09%)}%ykG<%QwZTg5j`6dFCZvO<7a%bB$iZf$|P?%I)$j-^WT*BtM|pZ4$4M zAa9Y=M)yK8K7;{TRuo=K#)yqUha}B&G;Hs?2hhG64bSvc*L#`@q9))jI>VDg9N*?v zzJY0%)weL6gu|E3oqP}Wy4s@wPd0J6h#v~Ek|Dt#k=Wix*UFPzzk{*8iKskvK$Ebq zMvE+|R&jNfCGFpXH0dB}58Z>x{+8}EeRJso(0SC`U*t`BpR{-Gr;J<@2>}aC#~eH3 H!Pxs7EBlIU literal 0 HcmV?d00001 diff --git a/__pycache__/routes.cpython-38.pyc b/__pycache__/routes.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe769253ac5ff93286985af09f88adb9e7b9ff3b GIT binary patch literal 6387 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 i40*JPHSy~B$<|9T}mCQ;ANM zXfed;jF-r30((cNL+oar6E{nAC}OuWUMwBbIOdoNqyj?)j(s`N`hP+HrT-t2a+M0C z0{=<@87;0Bb3Q3*YxOv-wS|5||1{=WItMGoL@UKyXemDZmREGn{U)$?G&XMcU{DlG^pvNO# literal 0 HcmV?d00001 diff --git a/models.py b/models.py new file mode 100644 index 0000000..ee1b4ab --- /dev/null +++ b/models.py @@ -0,0 +1,35 @@ +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime + +db = SQLAlchemy() + +class Company(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(50), nullable=False, unique=True) + tickets = db.relationship('Ticket', backref='company', lazy=True) + onsites = db.relationship('Onsite', backref='company', lazy=True) + +class Ticket(db.Model): + id = db.Column(db.Integer, primary_key=True) + company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False) + name = db.Column(db.String(100), nullable=False) + subject = db.Column(db.String(100), nullable=False) + ticket_number = db.Column(db.String(100), nullable=False) + status = db.Column(db.String(10), nullable=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) + closed_at = db.Column(db.DateTime, nullable=True) + archived = db.Column(db.Boolean, default=False, nullable=False) + +class Note(db.Model): + id = db.Column(db.Integer, primary_key=True) + ticket_id = db.Column(db.Integer, db.ForeignKey('ticket.id'), nullable=False) + note = db.Column(db.Text, nullable=False) + archive = db.Column(db.Boolean, default=False, nullable=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) + ticket = db.relationship('Ticket', backref=db.backref('notes', lazy=True)) + +class Onsite(db.Model): + id = db.Column(db.Integer, primary_key=True) + company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False) + day_of_week = db.Column(db.String(10), nullable=False) + note = db.Column(db.Text, nullable=False) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bb5cc46 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +Flask>=1.0 +Flask-SQLAlchemy +Flask-WTF diff --git a/routes.py b/routes.py new file mode 100644 index 0000000..a76f44d --- /dev/null +++ b/routes.py @@ -0,0 +1,151 @@ +from flask import render_template, redirect, url_for, request, jsonify +from models import db, Ticket, Note, Company, Onsite +from forms import TicketForm, NoteForm, CompanyForm, OnsiteForm +from datetime import datetime, date + +def register_routes(app): + + @app.route('/') + def index(): + today = date.today() + open_tickets = Ticket.query.filter(Ticket.status == 'Open', Ticket.archived == False).all() + closed_tickets = Ticket.query.filter(Ticket.status == 'Closed', Ticket.archived == False).all() + onsites = {day: Onsite.query.filter_by(day_of_week=day).all() for day in ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']} + return render_template('index.html', open_tickets=open_tickets, closed_tickets=closed_tickets, onsites=onsites) + + @app.route('/overview') + def overview(): + today = date.today() + open_tickets = Ticket.query.filter(Ticket.status == 'Open', Ticket.archived == False).all() + closed_tickets = Ticket.query.filter(Ticket.status == 'Closed', Ticket.archived == False).all() + onsites = {day: Onsite.query.filter_by(day_of_week=day).all() for day in ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']} + return render_template('overview.html', open_tickets=open_tickets, closed_tickets=closed_tickets, onsites=onsites) + + @app.route('/add_ticket', methods=['GET', 'POST']) + def add_ticket(): + form = TicketForm() + form.company.choices = [(company.id, company.name) for company in Company.query.all()] + if form.validate_on_submit(): + new_ticket = Ticket( + company_id=form.company.data, + name=form.name.data, + subject=form.subject.data, + ticket_number=form.ticket_number.data, + status=form.status.data, + created_at=datetime.utcnow() + ) + db.session.add(new_ticket) + db.session.commit() + return redirect(url_for('index')) + return render_template('add_ticket.html', form=form) + + @app.route('/add_note/', methods=['GET', 'POST']) + def add_note(ticket_id): + form = NoteForm() + ticket = Ticket.query.get(ticket_id) + if form.validate_on_submit(): + new_note = Note(ticket_id=ticket_id, note=form.note.data, created_at=datetime.utcnow()) + db.session.add(new_note) + db.session.commit() + return redirect(url_for('index')) + return render_template('add_note.html', form=form, ticket_id=ticket_id, ticket=ticket) + + @app.route('/close_ticket/', methods=['GET']) + def close_ticket(ticket_id): + ticket = Ticket.query.get(ticket_id) + if ticket: + ticket.status = 'Closed' + ticket.closed_at = datetime.utcnow() + db.session.commit() + return redirect(url_for('index')) + + @app.route('/archive_ticket/', methods=['GET']) + def archive_ticket(ticket_id): + ticket = Ticket.query.get(ticket_id) + if ticket: + ticket.archived = True + db.session.commit() + return redirect(url_for('index')) + + @app.route('/archive_note/', methods=['GET']) + def archive_note(note_id): + note = Note.query.get(note_id) + if note: + note.archive = True + db.session.commit() + return redirect(url_for('index')) + + @app.route('/delete_ticket/', methods=['GET']) + def delete_ticket(ticket_id): + ticket = Ticket.query.get(ticket_id) + if ticket: + db.session.delete(ticket) + db.session.commit() + return redirect(url_for('all_tickets')) + + @app.route('/all_tickets') + def all_tickets(): + closed_tickets = Ticket.query.filter_by(status='Closed').all() + open_tickets = Ticket.query.filter_by(status='Open').all() + return render_template('all_tickets.html', closed_tickets=closed_tickets, open_tickets=open_tickets) + + @app.route('/companies', methods=['GET', 'POST']) + def companies(): + form = CompanyForm() + if form.validate_on_submit(): + new_company = Company(name=form.name.data) + db.session.add(new_company) + db.session.commit() + return redirect(url_for('companies')) + all_companies = Company.query.all() + return render_template('companies.html', form=form, companies=all_companies) + + @app.route('/add_onsite', methods=['GET', 'POST']) + def add_onsite(): + form = OnsiteForm() + if form.validate_on_submit(): + new_onsite = Onsite( + company_id=form.company.data, + day_of_week=form.day_of_week.data, + note=form.note.data + ) + db.session.add(new_onsite) + db.session.commit() + return redirect(url_for('index')) + return render_template('add_onsite.html', form=form) + + @app.route('/delete_onsite/', methods=['GET']) + def delete_onsite(onsite_id): + onsite = Onsite.query.get(onsite_id) + if onsite: + db.session.delete(onsite) + db.session.commit() + return redirect(url_for('index')) + + @app.route('/update_ticket/', methods=['POST']) + def update_ticket(ticket_id): + data = request.get_json() + ticket = Ticket.query.get(ticket_id) + if ticket: + if data['field'] == 'company_id': + company = Company.query.filter_by(name=data['value']).first() + if company: + ticket.company_id = company.id + elif data['field'] == 'name': + ticket.name = data['value'] + elif data['field'] == 'subject': + ticket.subject = data['value'] + elif data['field'] == 'ticket_number': + ticket.ticket_number = data['value'] + db.session.commit() + return jsonify(success=True) + return jsonify(success=False), 400 + + @app.route('/reopen_ticket/', methods=['GET']) + def reopen_ticket(ticket_id): + ticket = Ticket.query.get(ticket_id) + if ticket: + ticket.status = 'Open' + ticket.archived = False + db.session.commit() + return redirect(url_for('index')) diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..8e59343 --- /dev/null +++ b/static/styles.css @@ -0,0 +1,30 @@ +body { + font-family: Arial, sans-serif; +} + +header, nav, main { + padding: 1em; +} + +header { + background-color: #f8f8f8; + border-bottom: 1px solid #ddd; +} + +nav ul { + list-style: none; + padding: 0; +} + +nav ul li { + display: inline; + margin-right: 10px; +} + +h1 { + font-size: 2em; +} + +h2 { + font-size: 1.5em; +} diff --git a/templates/add_note.html b/templates/add_note.html new file mode 100644 index 0000000..54a2ac7 --- /dev/null +++ b/templates/add_note.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block title %}Add Note{% endblock %} + +{% block content %} +

Add Note to {{ ticket.company.name }} - {{ ticket.name }} - {{ ticket.subject }} - {{ ticket.ticket_number }}

+
+ {{ form.hidden_tag() }} + {{ form.note.label }} {{ form.note() }}
+ {{ form.submit() }} +
+{% endblock %} diff --git a/templates/add_onsite.html b/templates/add_onsite.html new file mode 100644 index 0000000..c3aabc8 --- /dev/null +++ b/templates/add_onsite.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} + +{% block title %}Add Onsite{% endblock %} + +{% block content %} +

Add Onsite

+
+ {{ form.hidden_tag() }} +

+ {{ form.company.label }}
+ {{ form.company }} +

+

+ {{ form.day_of_week.label }}
+ {{ form.day_of_week }} +

+

+ {{ form.note.label }}
+ {{ form.note }} +

+

{{ form.submit }}

+
+{% endblock %} diff --git a/templates/add_ticket.html b/templates/add_ticket.html new file mode 100644 index 0000000..7630061 --- /dev/null +++ b/templates/add_ticket.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} + +{% block title %}Add Ticket{% endblock %} + +{% block content %} +

Add Ticket

+
+ {{ form.hidden_tag() }} +

+ {{ form.company.label }}
+ {{ form.company }} +

+

+ {{ form.name.label }}
+ {{ form.name }} +

+

+ {{ form.subject.label }}
+ {{ form.subject }} +

+

+ {{ form.ticket_number.label }}
+ {{ form.ticket_number }} +

+

+ {{ form.status.label }}
+ {{ form.status }} +

+

{{ form.submit }}

+
+{% endblock %} diff --git a/templates/all_tickets.html b/templates/all_tickets.html new file mode 100644 index 0000000..f0a1309 --- /dev/null +++ b/templates/all_tickets.html @@ -0,0 +1,85 @@ +{% extends "base.html" %} + +{% block title %}All Tickets{% endblock %} + +{% block content %} +

Closed Tickets

+
    + {% for ticket in closed_tickets %} +
  • + + {{ ticket.company.name }} + - + + {{ ticket.name }} + - + + {{ ticket.subject }} + - + + {{ ticket.ticket_number }} + + (Delete) + (Reopen) +
      + {% for note in ticket.notes %} + +
    • + {{ note.note }} - {{ note.created_at.strftime('%Y-%m-%d %H:%M:%S') }} +
    • + + {% endfor %} +
    +
  • + {% endfor %} +
+ +

Open Tickets

+
    + {% for ticket in open_tickets %} +
  • + + {{ ticket.company.name }} + - + + {{ ticket.name }} + - + + {{ ticket.subject }} + - + + {{ ticket.ticket_number }} + + (Delete) + (Close) +
      + {% for note in ticket.notes %} + +
    • + {{ note.note }} - {{ note.created_at.strftime('%Y-%m-%d %H:%M:%S') }} +
    • + + {% endfor %} +
    +
  • + {% endfor %} +
+ + +{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..c7bf49d --- /dev/null +++ b/templates/base.html @@ -0,0 +1,21 @@ + + + + + {% block title %}Daily Overview{% endblock %} + + +
+

Daily Overview

+ +
+
+ {% block content %}{% endblock %} +
+ + diff --git a/templates/companies.html b/templates/companies.html new file mode 100644 index 0000000..e235505 --- /dev/null +++ b/templates/companies.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block title %}Companies{% endblock %} + +{% block content %} +

Companies

+
    + {% for company in companies %} +
  • {{ company.name }}
  • + {% endfor %} +
+

Add a New Company

+
+ {{ form.hidden_tag() }} + {{ form.name.label }} {{ form.name() }}
+ {{ form.submit() }} +
+{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..87b4443 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,68 @@ +{% extends "base.html" %} + +{% block title %}Daily Overview - Home{% endblock %} + +{% block content %} + +

Open Tickets

+
    + {% for ticket in open_tickets %} +
  • + {{ ticket.company.name }} - {{ ticket.name }} - {{ ticket.subject }} - {{ ticket.ticket_number }} + (Close) +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • + X + {{ note.note }} +
    • + {% endif %} + {% endfor %} +
    + Add Note +

  • + {% endfor %} +
+

Closed Tickets

+
    + {% for ticket in closed_tickets %} +
  • + {{ ticket.company.name }} - {{ ticket.name }} - {{ ticket.subject }} - {{ ticket.ticket_number }} + (Archive) + (Reopen) +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • + {{ note.note }} +
    • + {% endif %} + {% endfor %} +
    + Add Note +

  • + {% endfor %} +
+

Onsite Schedule

+

+ Add Onsite +

+ {% for day in ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] %} + {% if onsites[day]|length > 0 %} +

{{ day }}

+
    + {% for onsite in onsites[day] %} +
  • + X + {{ onsite.company.name }} - {{ onsite.note }} +
  • + {% endfor %} +
+ {% endif %} + {% endfor %} + +

+ Printable Overview +

+{% endblock %} diff --git a/templates/overview.html b/templates/overview.html new file mode 100644 index 0000000..e2d22b6 --- /dev/null +++ b/templates/overview.html @@ -0,0 +1,55 @@ +{% extends "base.html" %} + +{% block title %}Printable Overview{% endblock %} + +{% block content %} +

Open Tickets

+
    + {% for ticket in open_tickets %} +
  • + {{ ticket.company.name }} - {{ ticket.name }} - {{ ticket.subject }} - {{ ticket.ticket_number }} +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • + {{ note.note }} +
    • + {% endif %} + {% endfor %} +
    +
  • + {% endfor %} +
+ +

Closed Tickets

+
    + {% for ticket in closed_tickets %} +
  • + {{ ticket.company.name }} - {{ ticket.name }} - {{ ticket.subject }} - {{ ticket.ticket_number }} +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • + {{ note.note }} +
    • + {% endif %} + {% endfor %} +
    +
  • + {% endfor %} +
+ +

Onsite Schedule

+ {% for day in ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] %} + {% if onsites[day]|length > 0 %} +

{{ day }}

+
    + {% for onsite in onsites[day] %} +
  • + {{ onsite.company.name }} - {{ onsite.note }} +
  • + {% endfor %} +
+ {% endif %} + {% endfor %} +{% endblock %} diff --git a/templates/v2_index.html b/templates/v2_index.html new file mode 100644 index 0000000..5d81358 --- /dev/null +++ b/templates/v2_index.html @@ -0,0 +1,85 @@ +{% extends "base.html" %} + +{% block title %}Daily Overview - Home{% endblock %} + +{% block content %} +
+

Open Tickets

+
    + {% for ticket in open_tickets %} +
  • +
    +
    + {{ ticket.company.name }} - + {{ ticket.name }} - + {{ ticket.subject }} - + {{ ticket.ticket_number }} +
    + Close +
    +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • + X + {{ note.note }} +
    • + {% endif %} + {% endfor %} +
    + Add Note +
  • + {% endfor %} +
+ +

Closed Tickets

+
    + {% for ticket in closed_tickets %} +
  • +
    +
    + {{ ticket.company.name }} - + {{ ticket.name }} - + {{ ticket.subject }} - + {{ ticket.ticket_number }} +
    +
    + Archive + Reopen +
    +
    +
      + {% for note in ticket.notes %} + {% if not note.archive %} +
    • {{ note.note }}
    • + {% endif %} + {% endfor %} +
    + Add Note +
  • + {% endfor %} +
+ +

Onsite Schedule

+

+ Add Onsite +

+ {% for day in ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] %} + {% if onsites[day]|length > 0 %} +

{{ day }}

+
    + {% for onsite in onsites[day] %} +
  • + {{ onsite.company.name }} - {{ onsite.note }} + X +
  • + {% endfor %} +
+ {% endif %} + {% endfor %} + +

+ Printable Overview +

+
+{% endblock %}