==============================================
Frontend Development
==============================================
To ensure that our look and feel is consistent with other Thunderbird Services we utilize VueJS and our Services-UI library.
The intention here is to not make an SPA, but to enhance existing django templates in a language the team is comfortable working in.
Overview
--------
* Create the Single File Component (SFC)
* Import the SFC in `app.js` and specify the target DOM ID (i.e., the mount point)
* Either:
* Update existing template, adding DOM ID
* Or create a new url route, view function, and template (that contains DOM ID)
* If necessary, pass Django variables to the SFC
Creating the SFC
----------------
Create a new `.vue` file in `assets/app/vue/components/`
Create this as a standalone Vue component that does not rely on props or routing.
Adding the SFC to `app.js`
--------------------------
Import your Vue component into `app.js`.
Update the `vueApps` array with an object that specifies:
* the DOM ID mount point
* your new Vue component
.. code-block:: javascript
import CheckoutFlow from '@/components/CheckoutFlow.vue';
const vueApps = [
{
id: 'checkoutFlow',
sfc: CheckoutFlow,
},
]
With this change, your SFC will automatically get mounted if the DOM ID exists.
Add DOM ID to template
----------------------
If you are adding the SFC to an existing template, add the element where the SFC should be mounted:
.. code-block:: django
{% extends 'mail/self-serve/_base.html' %}
{% block page_heading %}
Self Serve - Subscription
{% endblock %}
{% block body %}
{% endblock %}
Make sure to match the DOM ID specified in `app.js`
If you are creating a completely new page, you will need to create the URL route, the view function, and the template file.
Pass Django variables to SFC
----------------------------
If you need to supply the SFC with values from the Django application, do these two things:
1. Provide them to the template from the view function.
2. Add them to the `window._page` object in the template
This example renders `mail/self-serve/subscription.html` and provides context variables:
.. code-block:: python
def self_serve_subscription(request: HttpRequest):
"""Subscription page allowing user to select plan tier and do checkout via Paddle.js overlay"""
account = request.user.account_set.first()
return TemplateResponse(
request,
'mail/self-serve/subscription.html',
{
'is_subscription': True,
'success_redirect': reverse('self_serve_subscription_success'),
'paddle_token': settings.PADDLE_TOKEN,
'paddle_environment': settings.PADDLE_ENV,
'paddle_price_id_lo': settings.PADDLE_PRICE_ID_LO,
'paddle_price_id_md': settings.PADDLE_PRICE_ID_MD,
'paddle_price_id_hi': settings.PADDLE_PRICE_ID_HI,
**self_serve_common_options(False, account),
},
)
In the template, the context variables are attached to the `window` object:
.. code-block:: django
{% extends 'mail/self-serve/_base.html' %}
{% block page_heading %}
Self Serve - Subscription
{% endblock %}
{% block body %}
{% endblock %}
The SFC accesses and uses these values in the `