diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc index f8c5d2a..6d68df8 100644 Binary files a/app/__pycache__/routes.cpython-311.pyc and b/app/__pycache__/routes.cpython-311.pyc differ diff --git a/app/getpage.html b/app/getpage.html deleted file mode 100644 index 4402923..0000000 --- a/app/getpage.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends 'head.html' %} -{% block content %} - -
-
-
-

Hello there, CUSTOMER SUCCESS MANAGER.

- Northpass Full Color Logo -

Today is Monday 1, January 2000.

-
-

{{ request.form.apikey }}

-
-

Hello! Please select what you'd like to do.

-
-
- - -

Get Fucked

-
-
-
-
- - -

Get Fucked

-
-
-
-
- - {% endblock %} diff --git a/app/routes.py b/app/routes.py index 5a746ef..9b05885 100644 --- a/app/routes.py +++ b/app/routes.py @@ -8,61 +8,126 @@ import re @app.route("/", methods=["GET", "POST"]) def ask_key(): + session.clear() if request.method == "POST": - session['key'] = request.form.get('apikey') - print(session['key']) - flash(session['key']) - if re.search(r'(\S+\w+)', session['key']) and len(session['key']) > 5: - print("regex worked") - print(len(session['key'])) - return render_template("get.html", title="Options") + session["key"] = request.form.get("apikey") + if re.search("\s", session["key"]): + error = "Hm. That doesn't seem right" + return render_template("index.html", title="Home", error=error) + elif session["key"] is not None and len(session["key"]) > 10: + return render_template("options.html", title="Options") else: error = "Hm. That doesn't seem right" return render_template("index.html", title="Home", error=error) + else: return render_template("index.html", title="Home") +@app.route("/", methods=["GET", "POST"]) +def render_home(): + return render_template("index.html", title="Home") + + @app.route("/get_courses", methods=["GET", "POST"]) def get_courses(): array = [] df = pd.DataFrame() + tempdf = pd.DataFrame() + pd.set_option("display.max_colwidth", 100) + x = 0 + if request.method == "POST": - url = "https://api.northpass.com/v2/courses" - headers = {"accept": "application/json", "X-Api-Key": session['key']} - response = requests.get(url, headers=headers) - jsonresponse = response.json() - dt = jsonresponse["data"] - for course in dt: - df = df.append(course["attributes"], ignore_index=True) + while True: + x += 1 + url = f"https://api.northpass.com/v2/courses?page={x}" + headers = {"accept": "application/json", "X-Api-Key": session["key"]} + response = requests.get(url, headers=headers) + jsonresponse = response.json() + dt = jsonresponse["data"] + next = jsonresponse["links"] + + for course in dt: + df = df.append(course["attributes"], ignore_index=True) + df = df.drop("list_image_url", axis=1) + + if "next" not in next: + break + + dfhtml = df.to_html(col_space=5) + session["dfcsv"] = df.to_csv() + return render_template("table.html", tables=dfhtml, titles="Course List") + else: return "This isn't working. Let's go our own way." - print(df) - download = make_response(df.to_csv()) - download.headers["Content-Disposition"] = "attachment; filename=export.csv" - download.headers["Content-Type"] = "text/csv" - return download + + +@app.route("/table") +def table(): + return render_template("table.html", tables=[session["dfhtml"]], titles=["Table"]) + + +@app.route("/downloadcsv", methods=["GET", "POST"]) +def download_csv(): + if request.method == "GET": + download = make_response(session["dfcsv"]) + download.headers["Content-Disposition"] = "attachment; filename=export.csv" + download.headers["Content-Type"] = "text/csv" + return download @app.route("/get_people", methods=["GET", "POST"]) def get_people(): - print(session['key']) + array = [] + df = pd.DataFrame() + x = 0 + if request.method == "POST": - url = "https://api.northpass.com/v2/people" - headers = {"accept": "application/json", "X-Api-Key": session['key']} - response = requests.get(url, headers=headers) - jsonresponse = response.json() - dt = jsonresponse - person = dt - print(person) - return person + while True: + x += 1 + url = f"https://api.northpass.com/v2/people?page={x}" + headers = {"accept": "application/json", "X-Api-Key": session["key"]} + response = requests.get(url, headers=headers) + jsonresponse = response.json() + dt = jsonresponse["data"] + next = jsonresponse["links"] + + for person in dt: + print(person) + df = df.append(person["attributes"], ignore_index=True) + + if "next" not in next: + break + + dfppl = df.to_html(col_space=5) + session["dfcsv"] = df.to_csv() + return render_template("table.html", tables=dfppl, titles="People List") + else: return "what what" -@app.route("/startpage", methods=["GET", "POST"]) -def startpage(): - return render_template("startpage.html", title="StartTest") +@app.route("/add_options") +def add_options(): + return render_template("bulk_add.html", title="Bulk Add Learners") + + +@app.route("/bulk_add", methods=["GET", "POST"]) +def bulk_add(): + if request.method == "POST": + emails = request.form.get("emails") + groups = request.form.get("groups") + url = "https://api.northpass.com/v2/bulk/people" + + payload = { + "data": {"attributes": {"people": [{"email": emails, "groups": groups}]}} + } + + headers = { + "accept": "application/json", + "content-type": "application/json", + "X-Api-Key": session["key"], + } app.secret_key = "@&I\x1a?\xce\x94\xbb0w\x17\xbf&Y\xa2\xc2(A\xf5\xf2\x97\xba\xeb\xfa" diff --git a/app/static/app.js b/app/static/app.js deleted file mode 100644 index 485180f..0000000 --- a/app/static/app.js +++ /dev/null @@ -1,143 +0,0 @@ - -/*****************/ -/* EDITABLE INFO */ -/*****************/ - -/* -------------------------------------------------------- */ - -const NAME = "Norm"; - -const CARDS = [ - { - name: "Get all Users", - icon: "ri-admin-line", - link: "submit", - }, - { - name: "Get all Courses", - icon: "ri-mail-line", - link: "submit", - }, - { - name: "Get all Assignments", - icon: "ri-calendar-line", - link: "submit", - }, - ]; -/* -------------------------------------------------------- */ - -/******************/ -/* CLOCK FUNCTION */ -/******************/ - -const DAYS = [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", -]; - -const MONTHS = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -]; - -const updateDate = () => { - // Create a new Date object and get the complete Date/Time information - const completeDate = new Date(); - - // Time Variables - let currentHour = formatDigit(completeDate.getHours()); - let currentMinute = formatDigit(completeDate.getMinutes()); - - // Date Variables - let currentDay = completeDate.getDay(); - let currentNumber = completeDate.getDate(); - let currentMonth = completeDate.getMonth(); - let currentYear = completeDate.getFullYear(); - - // Update the Time - currentTime.innerHTML = `${ - currentHour % 12 == 0 ? "12" : currentHour % 12 - }:${currentMinute} ${currentHour > 11 ? "PM" : "AM"}`; - - // Update the Date - currentDate.innerHTML = `${DAYS[currentDay]} ${currentNumber}, ${MONTHS[currentMonth]} ${currentYear}`; - - // Create a Loop - setTimeout(() => { - updateDate(); - }, 1000); -}; - -const formatDigit = (digit) => { - return digit > 9 ? `${digit}` : `0${digit}`; -}; - -/******************/ -/* CARDS FUNCTION */ -/******************/ - -const printCards = () => { - for (const card of CARDS) { - let currentCard = document.createElement("a"); - let currentCardText = document.createElement("p"); - currentCardText.appendChild(document.createTextNode(card.name)); - let currentCardIcon = document.createElement("i"); - currentCardIcon.classList.add(card.icon); - - // Style the Card Element - currentCard.classList.add("card"); - currentCard.href = card.link; - - // Handle the click event - currentCard.addEventListener("click", async (event) => { - //document.forms["apiform"].submit(); - // Copy the href to the clipboard - try { - await navigator.clipboard.writeText(card.link); - currentCard.blur(); - currentCardText.innerText = "Saved to clipboard!"; - setTimeout(() => { - currentCardText.innerText = card.name; - }, 1500); - } catch { - currentCardText.innerText = "Unable to copy"; - setTimeout(() => { - currentCardText.innerText = card.name; - }, 1500); - } - }); - - // Style the Icon - currentCardIcon.classList.add("card__icon"); - - // Style the Text - currentCardText.classList.add("card__name"); - - currentCard.append(currentCardIcon); - currentCard.append(currentCardText); - cardContainer.appendChild(currentCard); - } -}; - -/****************/ -/* STARTER CODE */ -/****************/ - -userName.innerHTML = NAME; -printCards(); -updateDate(); diff --git a/app/static/css/styles.css b/app/static/css/styles.css index 2414e0b..e06c155 100644 --- a/app/static/css/styles.css +++ b/app/static/css/styles.css @@ -2,10 +2,12 @@ /* Custom Variables | Color Scheme */ :root { - --primary: #fff; - --text-light: #E5E9F0; - --background: #3B4252; - --background-light: #4C566A; + --primary: #66C92D; + --text-light: #FFFFFF; + --text-dark: #667E8A; + --background: #667E8A; + --background-light: #E5E9EB; + height: 100%; } *, @@ -17,21 +19,17 @@ } body { - margin-bottom: 0; - flex-grow: 1; - background: linear-gradient( + /*background: linear-gradient( 145deg, #81A1C1, #88C0D0, #8FBCBB, #A3BE8C, #EBCB8B, #D08770 ); background-size: 700% 550%; - animation: gradient 7s ease-in-out infinite; - height: 125vh; - margin-top: -100px; - padding-top: 100px; - color: var(--text-light); + animation: gradient 7s ease-in-out infinite;*/ + color: var(--text-dark); font-family: 'Space Grotesk', sans-serif; - padding: 2rem 4rem; - background-color: var(--background); + background-color: var(--background-light); box-sizing: border-box; + text-align: center; + width: 100%; } @keyframes gradient { @@ -46,6 +44,42 @@ body { } } +html { + display: flex; + justify-content: center; +} + +input, +select { + width: 200px; + height: 25px; + margin: 2px; + --moz-box-sizing: border-box; + --webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.dataframe { + font-size: 11pt; + border-collapse: collapse; + border: 1px solid #66C92D; + width: 100%; + text-align: left !important; +} + +.dataframe td, th { + padding: 5px; +} + +.dataframe tr:nth-child(even) { + background: #193D4F; +} + +.dataframe tr:hover { + background: #096F8E; + cursor: pointer; +} + h1 { font-size: 4rem; font-weight: bold; @@ -61,13 +95,11 @@ h4 { } img { - height: 50px; - width 500px; - align-items: flex-start; + height: 80px; } + main { margin: 4px; - display: flex; flex-wrap: wrap; justify-content: center; } @@ -75,9 +107,7 @@ main { .header { font-weight: 200; margin-top: 80px; - display: flex; justify-content: space-between; - align-items: center; } #currentDate { @@ -91,7 +121,7 @@ main { @media screen and (max-width: 1250px) { h1 { - display: none; + display: flex; } .header { @@ -107,7 +137,26 @@ main { text-align: center; } } +ul { + display: flex; +} +.card-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-auto-rows: 100px; + grid-gap: 2rem; + padding: 20px; +} + +.card { + background-color: #089FB7; + padding: 5px; + border-radius: 10px; + border: 1px solid #66C92D; + color: #FFFFFF; +} +/* .card:link, .card:visited { color: white; @@ -117,8 +166,6 @@ main { padding: 4rem 8rem; background-color: var(--background-light); - border-radius: 15px; - border: 1px solid #B48EAD; display: flex; justify-content: center; @@ -130,13 +177,10 @@ main { outline: none; transition: 0.1s; -} +}*/ .card:hover, .card:focus { - border-color: var(--primary); - color: var(--primary); - transform: scale(1.02); } @@ -151,17 +195,13 @@ main { .card__icon { font-size: 2rem; padding: 1rem; - background-color: #81A1C1; - border-radius: 50%; display: grid; - place-items: center; } .card__name { font-weight: 400; transform: translate(-50%, -50%); - position: absolute; - bottom: -25%; + position: relative; left: 50%; transition: 0.1s; } diff --git a/app/static/getallgroups.js b/app/static/getallgroups.js new file mode 100644 index 0000000..fecb43a --- /dev/null +++ b/app/static/getallgroups.js @@ -0,0 +1,40 @@ +document.addEventListener("DOMContentLoaded", function() { + getAllGroups(); +}); + +const apiKey = 'session["key"]'; +const groups= []; +const getAllGroups = async (num) => { + if(num === 1){ + } + let page = num; + + await axios({ + method: 'get', + url: `https://api.northpass.com/v2/groups?page=${page}`, + headers: { + 'accept': '*/*', + 'x-api-key': apiKey, + 'content-type': 'application/json' + } + }) + .then(async (res) => { + if (res.data.links.next != null) { + page++; + for (let i = 0; i < res.data.data.length; i++) { + let groupName = res.data.data[i].attributes.name; + selectInput = ''; + $('#groups').append(selectInput); + groups.push(res.data.data[i].attributes.name); + } + await getAllGroups(page); + } else { + for (let i = 0; i < res.data.data.length; i++) { + groups.push(res.data.data[i].attributes.name); + } + } + }) + .catch(err => { + console.log(err); + }) +} diff --git a/app/templates/bulk_add.html b/app/templates/bulk_add.html new file mode 100644 index 0000000..7500594 --- /dev/null +++ b/app/templates/bulk_add.html @@ -0,0 +1,24 @@ + +{% extends 'head.html' %} +{% block content %} +

Hello! Please enter the emails below.

+ {% if error %} +

{{ error }} + {% endif %} + +

+
+

Please Copy and Paste Emails of learners you'd like to add

+ +

Please select which Groups these learners should be added to.

+ +
+ + + + + + {% endblock %} + diff --git a/app/templates/get.html b/app/templates/get.html index 10cd20c..89498b6 100644 --- a/app/templates/get.html +++ b/app/templates/get.html @@ -1,21 +1,13 @@ + {% extends 'head.html' %} {% block content %} - -
-
-
-

Hello there, CUSTOMER SUCCESS MANAGER.

- Northpass Full Color Logo -

Today is Monday 1, January 2000.

-
-

{{ request.form.apikey }}

-

Hello! Please select what you'd like to do.

-
+
+
- @@ -23,19 +15,29 @@
-
-

Get Courses

-
+ +
+ + +

Get Courses

+
+ +
{% endblock %} diff --git a/app/templates/head.html b/app/templates/head.html index 8e98b7a..5d6c11b 100644 --- a/app/templates/head.html +++ b/app/templates/head.html @@ -9,12 +9,30 @@ rel="stylesheet" /> - CSM Bulk Actions + CSM Bulk App + + + +
+
+
+
+ + Northpass Full Color Logo + +
+
+ {% for message in get_flashed_messages() %} +

{{ message }}

+ {% endfor %} {% block content %} {% endblock %} diff --git a/app/templates/index.html b/app/templates/index.html index f4fd752..39dc221 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1,20 +1,15 @@ + {% extends 'head.html' %} {% block content %} - -
-
-
-

Hello there, CUSTOMER SUCCESS MANAGER.

- Northpass Full Color Logo -

Hello! Please click below to enter your key.

{% if error %} -

Error! {{ error }} +

{{ error }} {% endif %}

+
{% endblock %} diff --git a/app/templates/options.html b/app/templates/options.html new file mode 100644 index 0000000..53f711a --- /dev/null +++ b/app/templates/options.html @@ -0,0 +1,40 @@ + +{% extends 'head.html' %} +{% block content %} +

Hello! Please select what you'd like to do.

+
+
+
+ + +

Get People

+
+
+ +
+ + +

Get Courses

+
+
+ +
+ + +

Bulk Add

+
+ + +
+ + {% endblock %} diff --git a/app/templates/table.html b/app/templates/table.html new file mode 100644 index 0000000..63384dc --- /dev/null +++ b/app/templates/table.html @@ -0,0 +1,17 @@ + + +{% extends 'head.html' %} +{% block content %} +

Hello! Here are your results.

+ Click here to download as CSV. +
+
+ + {% for table in tables %} +

{{ titles }}

+ {{ table | safe }} + {% endfor %} +
+ + + {% endblock %}