diff --git a/.gitignore b/.gitignore
index 067d532a5d..4d83b1215e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -198,3 +198,9 @@ cypress/videos
.helix/
# Aider AI Chat
.aider*
+
+# frappecloud billing
+billing/node_modules
+frappe/public/billing
+billing/yarn.lock
+frappe/www/billing.html
diff --git a/billing/.gitignore b/billing/.gitignore
new file mode 100644
index 0000000000..53f7466aca
--- /dev/null
+++ b/billing/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local
\ No newline at end of file
diff --git a/billing/.prettierrc.json b/billing/.prettierrc.json
new file mode 100644
index 0000000000..b2095be81e
--- /dev/null
+++ b/billing/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/billing/README.md b/billing/README.md
new file mode 100644
index 0000000000..1a41f83ece
--- /dev/null
+++ b/billing/README.md
@@ -0,0 +1,42 @@
+# Frappe UI Starter
+
+This template should help get you started developing custom frontend for Frappe
+apps with Vue 3 and the Frappe UI package.
+
+This boilerplate sets up Vue 3, Vue Router, TailwindCSS, and Frappe UI out of
+the box.
+
+## Usage
+
+This template is meant to be cloned inside an existing Frappe App. Assuming your
+apps name is `todo`. Clone this template in the root folder of your app using `degit`.
+
+```
+cd apps/todo
+npx degit netchampfaris/frappe-ui-starter frontend
+cd frontend
+yarn
+yarn dev
+```
+
+In a development environment, you need to put the below key-value pair in your `site_config.json` file:
+
+```
+"ignore_csrf": 1
+```
+
+This will prevent `CSRFToken` errors while using the vite dev server. In production environment, the `csrf_token` is attached to the `window` object in `index.html` for you.
+
+The Vite dev server will start on the port `8080`. This can be changed from `vite.config.js`.
+The development server is configured to proxy your frappe app (usually running on port `8000`). If you have a site named `todo.test`, open `http://todo.test:8080` in your browser. If you see a button named "Click to send 'ping' request", congratulations!
+
+If you notice the browser URL is `/frontend`, this is the base URL where your frontend app will run in production.
+To change this, open `src/router.js` and change the base URL passed to `createWebHistory`.
+
+## Resources
+
+- [Vue 3](https://v3.vuejs.org/guide/introduction.html)
+- [Vue Router](https://next.router.vuejs.org/guide/)
+- [Frappe UI](https://github.com/frappe/frappe-ui)
+- [TailwindCSS](https://tailwindcss.com/docs/utility-first)
+- [Vite](https://vitejs.dev/guide/)
diff --git a/billing/index.html b/billing/index.html
new file mode 100644
index 0000000000..4b782454be
--- /dev/null
+++ b/billing/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Billing
+
+
+
+
+
+
+
+
+
diff --git a/billing/package.json b/billing/package.json
new file mode 100644
index 0000000000..2456d67b73
--- /dev/null
+++ b/billing/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "billing-ui",
+ "private": true,
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build --base=/assets/frappe/billing/ && yarn copy-html-entry",
+ "copy-html-entry": "cp ../frappe/public/billing/index.html ../frappe/www/billing.html",
+ "serve": "vite preview"
+ },
+ "dependencies": {
+ "frappe-ui": "^v0.1.72",
+ "tailwindcss": "^3.3.3",
+ "vue": "^3.4.12"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^4.2.3",
+ "autoprefixer": "^10.4.14",
+ "postcss": "^8.4.5",
+ "vite": "^4"
+ }
+}
diff --git a/billing/postcss.config.js b/billing/postcss.config.js
new file mode 100644
index 0000000000..33ad091d26
--- /dev/null
+++ b/billing/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/billing/public/favicon.png b/billing/public/favicon.png
new file mode 100644
index 0000000000..b51db82f82
Binary files /dev/null and b/billing/public/favicon.png differ
diff --git a/billing/src/App.vue b/billing/src/App.vue
new file mode 100644
index 0000000000..2d3067be64
--- /dev/null
+++ b/billing/src/App.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/billing/src/assets/Inter/Inter-Black.woff b/billing/src/assets/Inter/Inter-Black.woff
new file mode 100644
index 0000000000..c7737ed3d8
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Black.woff differ
diff --git a/billing/src/assets/Inter/Inter-Black.woff2 b/billing/src/assets/Inter/Inter-Black.woff2
new file mode 100644
index 0000000000..b16b995bee
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Black.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-BlackItalic.woff b/billing/src/assets/Inter/Inter-BlackItalic.woff
new file mode 100644
index 0000000000..b5f1447643
Binary files /dev/null and b/billing/src/assets/Inter/Inter-BlackItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-BlackItalic.woff2 b/billing/src/assets/Inter/Inter-BlackItalic.woff2
new file mode 100644
index 0000000000..a3f1b70cdf
Binary files /dev/null and b/billing/src/assets/Inter/Inter-BlackItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Bold.woff b/billing/src/assets/Inter/Inter-Bold.woff
new file mode 100644
index 0000000000..e38455587f
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Bold.woff differ
diff --git a/billing/src/assets/Inter/Inter-Bold.woff2 b/billing/src/assets/Inter/Inter-Bold.woff2
new file mode 100644
index 0000000000..835dd4977a
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Bold.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-BoldItalic.woff b/billing/src/assets/Inter/Inter-BoldItalic.woff
new file mode 100644
index 0000000000..ffac3f59b5
Binary files /dev/null and b/billing/src/assets/Inter/Inter-BoldItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-BoldItalic.woff2 b/billing/src/assets/Inter/Inter-BoldItalic.woff2
new file mode 100644
index 0000000000..1a41a14ff1
Binary files /dev/null and b/billing/src/assets/Inter/Inter-BoldItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-ExtraBold.woff b/billing/src/assets/Inter/Inter-ExtraBold.woff
new file mode 100644
index 0000000000..885ac94fbf
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraBold.woff differ
diff --git a/billing/src/assets/Inter/Inter-ExtraBold.woff2 b/billing/src/assets/Inter/Inter-ExtraBold.woff2
new file mode 100644
index 0000000000..ae956b1501
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraBold.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff b/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff
new file mode 100644
index 0000000000..d6cf862332
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff2 b/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff2
new file mode 100644
index 0000000000..86578995d2
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraBoldItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-ExtraLight.woff b/billing/src/assets/Inter/Inter-ExtraLight.woff
new file mode 100644
index 0000000000..ff76919327
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraLight.woff differ
diff --git a/billing/src/assets/Inter/Inter-ExtraLight.woff2 b/billing/src/assets/Inter/Inter-ExtraLight.woff2
new file mode 100644
index 0000000000..694b2df9fa
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraLight.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-ExtraLightItalic.woff b/billing/src/assets/Inter/Inter-ExtraLightItalic.woff
new file mode 100644
index 0000000000..c6ed13a4ff
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraLightItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-ExtraLightItalic.woff2 b/billing/src/assets/Inter/Inter-ExtraLightItalic.woff2
new file mode 100644
index 0000000000..9a7bd11090
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ExtraLightItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Italic.woff b/billing/src/assets/Inter/Inter-Italic.woff
new file mode 100644
index 0000000000..4fdb59dc2d
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Italic.woff differ
diff --git a/billing/src/assets/Inter/Inter-Italic.woff2 b/billing/src/assets/Inter/Inter-Italic.woff2
new file mode 100644
index 0000000000..deca637d81
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Italic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Light.woff b/billing/src/assets/Inter/Inter-Light.woff
new file mode 100644
index 0000000000..42850acc03
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Light.woff differ
diff --git a/billing/src/assets/Inter/Inter-Light.woff2 b/billing/src/assets/Inter/Inter-Light.woff2
new file mode 100644
index 0000000000..65a7dadddb
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Light.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-LightItalic.woff b/billing/src/assets/Inter/Inter-LightItalic.woff
new file mode 100644
index 0000000000..c4ed9a94fa
Binary files /dev/null and b/billing/src/assets/Inter/Inter-LightItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-LightItalic.woff2 b/billing/src/assets/Inter/Inter-LightItalic.woff2
new file mode 100644
index 0000000000..555fc55955
Binary files /dev/null and b/billing/src/assets/Inter/Inter-LightItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Medium.woff b/billing/src/assets/Inter/Inter-Medium.woff
new file mode 100644
index 0000000000..495faef7ff
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Medium.woff differ
diff --git a/billing/src/assets/Inter/Inter-Medium.woff2 b/billing/src/assets/Inter/Inter-Medium.woff2
new file mode 100644
index 0000000000..871ce4ce5d
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Medium.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-MediumItalic.woff b/billing/src/assets/Inter/Inter-MediumItalic.woff
new file mode 100644
index 0000000000..389c7a2bfe
Binary files /dev/null and b/billing/src/assets/Inter/Inter-MediumItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-MediumItalic.woff2 b/billing/src/assets/Inter/Inter-MediumItalic.woff2
new file mode 100644
index 0000000000..aa8057992b
Binary files /dev/null and b/billing/src/assets/Inter/Inter-MediumItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Regular.woff b/billing/src/assets/Inter/Inter-Regular.woff
new file mode 100644
index 0000000000..fa7715d120
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Regular.woff differ
diff --git a/billing/src/assets/Inter/Inter-Regular.woff2 b/billing/src/assets/Inter/Inter-Regular.woff2
new file mode 100644
index 0000000000..b52dd0a0b7
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Regular.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-SemiBold.woff b/billing/src/assets/Inter/Inter-SemiBold.woff
new file mode 100644
index 0000000000..18d7749f56
Binary files /dev/null and b/billing/src/assets/Inter/Inter-SemiBold.woff differ
diff --git a/billing/src/assets/Inter/Inter-SemiBold.woff2 b/billing/src/assets/Inter/Inter-SemiBold.woff2
new file mode 100644
index 0000000000..ece5204a19
Binary files /dev/null and b/billing/src/assets/Inter/Inter-SemiBold.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-SemiBoldItalic.woff b/billing/src/assets/Inter/Inter-SemiBoldItalic.woff
new file mode 100644
index 0000000000..8ee64396a0
Binary files /dev/null and b/billing/src/assets/Inter/Inter-SemiBoldItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-SemiBoldItalic.woff2 b/billing/src/assets/Inter/Inter-SemiBoldItalic.woff2
new file mode 100644
index 0000000000..b32c0ba3bd
Binary files /dev/null and b/billing/src/assets/Inter/Inter-SemiBoldItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-Thin.woff b/billing/src/assets/Inter/Inter-Thin.woff
new file mode 100644
index 0000000000..1a22286f6e
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Thin.woff differ
diff --git a/billing/src/assets/Inter/Inter-Thin.woff2 b/billing/src/assets/Inter/Inter-Thin.woff2
new file mode 100644
index 0000000000..c56bc7ca6d
Binary files /dev/null and b/billing/src/assets/Inter/Inter-Thin.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-ThinItalic.woff b/billing/src/assets/Inter/Inter-ThinItalic.woff
new file mode 100644
index 0000000000..d8ec8373ac
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ThinItalic.woff differ
diff --git a/billing/src/assets/Inter/Inter-ThinItalic.woff2 b/billing/src/assets/Inter/Inter-ThinItalic.woff2
new file mode 100644
index 0000000000..eca5608c0f
Binary files /dev/null and b/billing/src/assets/Inter/Inter-ThinItalic.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-italic.var.woff2 b/billing/src/assets/Inter/Inter-italic.var.woff2
new file mode 100644
index 0000000000..1f5d92611a
Binary files /dev/null and b/billing/src/assets/Inter/Inter-italic.var.woff2 differ
diff --git a/billing/src/assets/Inter/Inter-roman.var.woff2 b/billing/src/assets/Inter/Inter-roman.var.woff2
new file mode 100644
index 0000000000..05621d8d16
Binary files /dev/null and b/billing/src/assets/Inter/Inter-roman.var.woff2 differ
diff --git a/billing/src/assets/Inter/Inter.var.woff2 b/billing/src/assets/Inter/Inter.var.woff2
new file mode 100644
index 0000000000..46bb515393
Binary files /dev/null and b/billing/src/assets/Inter/Inter.var.woff2 differ
diff --git a/billing/src/assets/Inter/inter.css b/billing/src/assets/Inter/inter.css
new file mode 100644
index 0000000000..3ca1bbf655
--- /dev/null
+++ b/billing/src/assets/Inter/inter.css
@@ -0,0 +1,152 @@
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 100;
+ font-display: swap;
+ src: url("Inter-Thin.woff2?v=3.12") format("woff2"),
+ url("Inter-Thin.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 100;
+ font-display: swap;
+ src: url("Inter-ThinItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-ThinItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 200;
+ font-display: swap;
+ src: url("Inter-ExtraLight.woff2?v=3.12") format("woff2"),
+ url("Inter-ExtraLight.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 200;
+ font-display: swap;
+ src: url("Inter-ExtraLightItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-ExtraLightItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 300;
+ font-display: swap;
+ src: url("Inter-Light.woff2?v=3.12") format("woff2"),
+ url("Inter-Light.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 300;
+ font-display: swap;
+ src: url("Inter-LightItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-LightItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url("Inter-Regular.woff2?v=3.12") format("woff2"),
+ url("Inter-Regular.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 400;
+ font-display: swap;
+ src: url("Inter-Italic.woff2?v=3.12") format("woff2"),
+ url("Inter-Italic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url("Inter-Medium.woff2?v=3.12") format("woff2"),
+ url("Inter-Medium.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 500;
+ font-display: swap;
+ src: url("Inter-MediumItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-MediumItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url("Inter-SemiBold.woff2?v=3.12") format("woff2"),
+ url("Inter-SemiBold.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 600;
+ font-display: swap;
+ src: url("Inter-SemiBoldItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-SemiBoldItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url("Inter-Bold.woff2?v=3.12") format("woff2"),
+ url("Inter-Bold.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 700;
+ font-display: swap;
+ src: url("Inter-BoldItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-BoldItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 800;
+ font-display: swap;
+ src: url("Inter-ExtraBold.woff2?v=3.12") format("woff2"),
+ url("Inter-ExtraBold.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 800;
+ font-display: swap;
+ src: url("Inter-ExtraBoldItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-ExtraBoldItalic.woff?v=3.12") format("woff");
+}
+
+@font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 900;
+ font-display: swap;
+ src: url("Inter-Black.woff2?v=3.12") format("woff2"),
+ url("Inter-Black.woff?v=3.12") format("woff");
+}
+@font-face {
+ font-family: 'Inter';
+ font-style: italic;
+ font-weight: 900;
+ font-display: swap;
+ src: url("Inter-BlackItalic.woff2?v=3.12") format("woff2"),
+ url("Inter-BlackItalic.woff?v=3.12") format("woff");
+}
diff --git a/billing/src/index.css b/billing/src/index.css
new file mode 100644
index 0000000000..e2fc4dd51a
--- /dev/null
+++ b/billing/src/index.css
@@ -0,0 +1,26 @@
+@import './assets/Inter/inter.css';
+@import 'frappe-ui/src/style.css';
+
+@layer components {
+ .prose-f {
+ @apply
+ break-all
+ max-w-none
+ prose
+ prose-code:break-all
+ prose-code:whitespace-pre-wrap
+ prose-img:border
+ prose-img:rounded-lg
+ prose-sm
+ prose-table:table-fixed
+ prose-td:border
+ prose-td:border-gray-300
+ prose-td:p-2
+ prose-td:relative
+ prose-th:bg-gray-100
+ prose-th:border
+ prose-th:border-gray-300
+ prose-th:p-2
+ prose-th:relative
+ }
+}
\ No newline at end of file
diff --git a/billing/src/main.js b/billing/src/main.js
new file mode 100644
index 0000000000..c323e0086c
--- /dev/null
+++ b/billing/src/main.js
@@ -0,0 +1,8 @@
+import './index.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+let app = createApp(App)
+
+app.mount('#app')
diff --git a/billing/tailwind.config.js b/billing/tailwind.config.js
new file mode 100644
index 0000000000..da6bf60a84
--- /dev/null
+++ b/billing/tailwind.config.js
@@ -0,0 +1,17 @@
+module.exports = {
+ presets: [require('frappe-ui/src/utils/tailwind.config')],
+ content: [
+ './index.html',
+ './src/**/*.{vue,js,ts,jsx,tsx}',
+ './node_modules/frappe-ui/src/components/**/*.{vue,js,ts,jsx,tsx}',
+ '../node_modules/frappe-ui/src/components/**/*.{vue,js,ts,jsx,tsx}',
+ ],
+ safelist: [
+ { pattern: /!(text|bg)-/, variants: ['hover', 'active'] },
+ { pattern: /^grid-cols-/ },
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
diff --git a/billing/vite.config.js b/billing/vite.config.js
new file mode 100644
index 0000000000..63133c6698
--- /dev/null
+++ b/billing/vite.config.js
@@ -0,0 +1,48 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import path from 'path'
+import frappeui from 'frappe-ui/vite'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ frappeui(),
+ vue(),
+ {
+ name: 'transform-index.html',
+ transformIndexHtml(html, context) {
+ if (!context.server) {
+ return html.replace(
+ /<\/body>/,
+ `
+
+