diff --git a/static/js/src/advantage/credentials/api/keys.js b/static/js/src/advantage/credentials/api/keys.js index 1364c78a17e..4fe67291884 100644 --- a/static/js/src/advantage/credentials/api/keys.js +++ b/static/js/src/advantage/credentials/api/keys.js @@ -24,15 +24,3 @@ export async function rotateKey(activationKey) { const data = await response.json(); return data; } - -export async function getExamProducts() { - let response = await fetch("/credentials/exam/products", { - method: "GET", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }); - const data = await response.json(); - return data; -} diff --git a/static/js/src/advantage/credentials/app.tsx b/static/js/src/advantage/credentials/app.tsx index dabde0d9954..9eef87ed2ce 100644 --- a/static/js/src/advantage/credentials/app.tsx +++ b/static/js/src/advantage/credentials/app.tsx @@ -6,7 +6,6 @@ import { Integrations } from "@sentry/tracing"; import { ReactQueryDevtools } from "react-query/devtools"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import CredManage from "./components/CredManage"; -import CredExamShop from "./components/CredExamShop/CredExamShop"; const oneHour = 1000 * 60 * 60; const queryClient = new QueryClient({ @@ -37,7 +36,6 @@ function App() { - } /> } /> diff --git a/static/js/src/advantage/credentials/components/CredExamShop/CredExamShop.tsx b/static/js/src/advantage/credentials/components/CredExamShop/CredExamShop.tsx deleted file mode 100644 index 9b7be466f41..00000000000 --- a/static/js/src/advantage/credentials/components/CredExamShop/CredExamShop.tsx +++ /dev/null @@ -1,265 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { - Button, - Col, - RadioInput, - Row, - Strip, - Spinner, -} from "@canonical/react-components"; -import classNames from "classnames"; -import { currencyFormatter } from "advantage/react/utils"; -import { Product } from "advantage/credentials/utils/utils"; -import { useQuery } from "react-query"; -import { getExamProducts } from "advantage/credentials/api/keys"; - -const CredExamShop = () => { - const ExamProductDescriptions: Product[] = [ - { - id: "cue-linux-essentials", - name: "CUE.01 Linux", - displayName: "CUE.01 Linux", - metadata: [ - { - key: "description", - value: - "Prove your basic operational knowledge of Linux by demonstrating your ability to secure, operate and maintain basic system resources. Topics include user and group management, file and filesystem navigation, and logs and installation tasks related to system maintenance.", - }, - { - key: "originalPrice", - value: "10000", - }, - ], - }, - { - id: "cue-02-desktop", - name: "CUE.02 Desktop", - displayName: "CUE.02 Desktop", - metadata: [ - { - key: "description", - value: - "Demonstrate your knowledge of Ubuntu Desktop administrative essentials. Topics include package management, system installation, data gathering, and managing printing and displays.", - }, - ], - }, - { - id: "cue-03-server", - name: "CUE.03 Server", - displayName: "CUE.03 Server", - metadata: [ - { - key: "description", - value: - "Illustrate your knowledge of common Ubuntu Server administrative tasks and troubleshooting. Topics include job control, performance tuning, services management, and Bash scripting.", - }, - ], - }, - ]; - const { isLoading, data: ExamData } = useQuery(["ExamProducts"], async () => { - return getExamProducts(); - }); - const [ExamProducts, setExamProducts] = useState([]); - const [exam, setExam] = useState(0); - const handleChange = (event: React.ChangeEvent) => { - setExam(parseInt(event.target.value)); - localStorage.setItem("exam-selector", JSON.stringify(event?.target.value)); - }; - const handleSubmit = ( - event: - | React.FormEvent - | React.MouseEvent - ) => { - event.preventDefault(); - localStorage.setItem( - "shop-checkout-data", - JSON.stringify({ - product: ExamProducts[exam], - quantity: 1, - action: "purchase", - }) - ); - location.href = "/account/checkout"; - }; - useEffect(() => { - if (ExamData === undefined) { - return; - } - for (const examDescription of ExamProductDescriptions) { - for (const exam of ExamData) { - if (exam.id === examDescription.id) { - Object.assign(examDescription, exam); - } - } - } - setExamProducts(ExamProductDescriptions); - }, [ExamData]); - if (isLoading) { - return ; - } - - return ( - <> - - -

Select an exam to purchase

-
- - {ExamProducts.map((examElement, examIndex) => { - return ( - -
- -
- - ); - })} -
- {ExamProducts.map((examElement, examIndex) => { - return ( - -
- - -

- {examElement.metadata[0].value} -

-
- -
- {examElement.price === undefined ? ( - Coming Soon - ) : ( - - Price:{" "} - {examElement.metadata[1].value !== undefined ? ( - - {currencyFormatter.format( - parseInt(examElement.metadata[1].value) / 100 - )} - - ) : ( - <> - )}{" "} - {currencyFormatter.format( - examElement.price.value / 100 - )} - - )} -
-
-
- - ); - })} -
-
- - - Your Order - - - - -

- {ExamProducts[exam]?.displayName} -

- - -

- {currencyFormatter.format( - (ExamProducts[exam]?.price?.value ?? 0) / 100 ?? 0 - )} -

- - - - -
-
- - ); -}; -export default CredExamShop; diff --git a/static/js/src/advantage/credentials/components/CredExamShop/index.tsx b/static/js/src/advantage/credentials/components/CredExamShop/index.tsx deleted file mode 100644 index 5a773316687..00000000000 --- a/static/js/src/advantage/credentials/components/CredExamShop/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./CredExamShop"; diff --git a/templates/credentials/shop/index.html b/templates/credentials/shop/index.html index 032b7e4e8b3..59b686eea00 100644 --- a/templates/credentials/shop/index.html +++ b/templates/credentials/shop/index.html @@ -3,27 +3,185 @@ {% block title %}Canonical Certification{% endblock %} {% block meta_description %} - The Canonical Ubuntu Essentials exams certify knowledge and verify skills in general Linux, - Ubuntu Desktop, and Ubuntu Server topics. + The Canonical Ubuntu Essentials exams certify knowledge and verify skills in general Linux, + Ubuntu Desktop, and Ubuntu Server topics. {% endblock meta_description %} {% block content %} -
-
-
-
-
- Loading… -
-
-
+
+
+
+

Select an exam to purchase

+
+
+ {% for exam in exams %} + {% set metadata_length = exam.metadata|length %} + {% set is_disabled = metadata_length == 1 %} + {% set is_discounted = True if metadata_length > 1 and exam.metadata[1].discountPrice else False %} +
+
+ +
+
+ {% endfor %} +
+ + + {% for exam in exams %} + {% set metadata_length = exam.metadata|length %} + {% set is_disabled = metadata_length == 1 %} + {% set is_discounted = True if metadata_length > 1 and exam.metadata[1].discountPrice else False %} +
+
+ + +

{{ exam.metadata[0].value }}

+
+ +
+ {% if is_disabled %} + Coming Soon! + {% else %} + Price: + {% if is_discounted %}{{ exam.metadata[1].currency }}{{ exam.metadata[1].originalPrice }}{% endif %} + {{ exam.metadata[1].currency }} + {% if is_discounted %} + {{ exam.metadata[1].discountPrice }} + {% else %} + {{ exam.metadata[1].originalPrice }} + {% endif %} + + {% endif %} +
+
+
+ {% endfor %}
- - +
+
+
Your Order
+
+
+ {% set exam = exams[exam_index] %} + {% set is_discounted = True if exam.metadata|length > 1 and exam.metadata[1].discountPrice else False %} +
+

{{ exam.displayName }}

+
+
+

+ + {% if is_discounted %} + {{ exam.metadata[1].currency }}{{ exam.metadata[1].discountPrice }} + {% else %} + {{ exam.metadata[1].currency }}{{ exam.metadata[1].originalPrice }} + {% endif %} + +

+
+
+ +
+
+
+
+ + {% endblock %} diff --git a/webapp/shop/cred/exams.json b/webapp/shop/cred/exams.json new file mode 100644 index 00000000000..3350a2b5c69 --- /dev/null +++ b/webapp/shop/cred/exams.json @@ -0,0 +1,43 @@ +[ + { + "id": "cue-linux-essentials", + "name": "CUE.01 Linux", + "displayName": "CUE.01 Linux", + "metadata": [ + { + "key": "description", + "value": + "Prove your basic operational knowledge of Linux by demonstrating your ability to secure, operate and maintain basic system resources. Topics include user and group management, file and filesystem navigation, and logs and installation tasks related to system maintenance." + }, + { + "originalPrice": "100.00", + "discountPrice": "0.00" , + "currency": "$" + } + ] + }, + { + "id": "cue-02-desktop", + "name": "CUE.02 Desktop", + "displayName": "CUE.02 Desktop", + "metadata": [ + { + "key": "description", + "value": + "Demonstrate your knowledge of Ubuntu Desktop administrative essentials. Topics include package management, system installation, data gathering, and managing printing and displays." + } + ] + }, + { + "id": "cue-03-server", + "name": "CUE.03 Server", + "displayName": "CUE.03 Server", + "metadata": [ + { + "key": "description", + "value": + "Illustrate your knowledge of common Ubuntu Server administrative tasks and troubleshooting. Topics include job control, performance tuning, services management, and Bash scripting." + } + ] + } +] \ No newline at end of file diff --git a/webapp/shop/cred/views.py b/webapp/shop/cred/views.py index 952e33131a5..1abd820a9a1 100644 --- a/webapp/shop/cred/views.py +++ b/webapp/shop/cred/views.py @@ -856,7 +856,22 @@ def cred_submit_form(**_): @shop_decorator(area="cube", permission="user", response="html") @canonical_staff() def cred_shop(**kwargs): - return flask.render_template("credentials/shop/index.html") + exams_file = open("webapp/shop/cred/exams.json", "r") + exams = json.load(exams_file) + cue_products = get_cue_products(type="exam").json + for product in cue_products: + for exam in exams: + if product["id"] == exam["id"]: + exam["longId"] = product["longId"] + exam["period"] = product["period"] + exam["marketplace"] = product["marketplace"] + exam["name"] = product["name"] + + return flask.render_template( + "credentials/shop/index.html", + exams=exams, + exam_index=0, + ) @shop_decorator(area="cube", permission="user", response="html")