diff --git a/cardie/main/templates/beta/base.html b/cardie/main/templates/beta/base.html new file mode 100644 index 0000000..7a55cf2 --- /dev/null +++ b/cardie/main/templates/beta/base.html @@ -0,0 +1,32 @@ +{% load static %} + + + + {% block head_scripts %} + {% endblock head_scripts %} + + + + + {% block stylesheets %}{% endblock %} + + + + + Cardie | + {% block head_title %}{% endblock %} + + + + + {% block body %}{% endblock %} + {% comment %} {% include "footer.html" %} {% endcomment %} + {% block scripts %}{% endblock %} + + diff --git a/cardie/main/templates/beta/editor.html b/cardie/main/templates/beta/editor.html new file mode 100644 index 0000000..7da63b0 --- /dev/null +++ b/cardie/main/templates/beta/editor.html @@ -0,0 +1,50 @@ +{% extends "beta/base.html" %} + +{% load static %} + +{% block stylesheets %} + + +{% endblock %} + +{% block body %} +
+
+ + +

Editor

+
+
+
+
+ + + + +
+
+
+ +
+
+ +
+{% endblock %} + +{% block scripts %} + + +{% endblock %} diff --git a/cardie/main/urls.py b/cardie/main/urls.py index 0a1a531..557719f 100644 --- a/cardie/main/urls.py +++ b/cardie/main/urls.py @@ -24,4 +24,5 @@ path("getwallet", views.get_wallet, name="getwallet"), path("removefromwallet", views.remove_from_wallet, name="removefromwallet"), path("config.js", views.config_js, name="config_js"), + path("beta/editor", views.beta_editor, name="beta_editor"), ] diff --git a/cardie/main/views.py b/cardie/main/views.py index df1e010..02cf768 100644 --- a/cardie/main/views.py +++ b/cardie/main/views.py @@ -350,3 +350,7 @@ def remove_from_wallet(request): def config_js(request): return render(request, "config.js", {}, content_type="text/javascript") + + +def beta_editor(request): + return render(request, "beta/editor.html") diff --git a/cardie/static/beta/card.js b/cardie/static/beta/card.js new file mode 100644 index 0000000..e314858 --- /dev/null +++ b/cardie/static/beta/card.js @@ -0,0 +1,21 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store, flipped: false }; + }, + methods: { + flip() { + this.flipped = !this.flipped; + }, + }, + template: `
+ + +
`, +}; diff --git a/cardie/static/beta/card_back.js b/cardie/static/beta/card_back.js new file mode 100644 index 0000000..ff079e4 --- /dev/null +++ b/cardie/static/beta/card_back.js @@ -0,0 +1,14 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + template: `
+
`, +}; diff --git a/cardie/static/beta/card_front.js b/cardie/static/beta/card_front.js new file mode 100644 index 0000000..9b7dcf9 --- /dev/null +++ b/cardie/static/beta/card_front.js @@ -0,0 +1,22 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + template: `
+
+

{{ store.card.front.title }}

+

{{ store.card.front.subTitle }}

+
+
`, +}; diff --git a/cardie/static/beta/editor.js b/cardie/static/beta/editor.js new file mode 100644 index 0000000..28718cf --- /dev/null +++ b/cardie/static/beta/editor.js @@ -0,0 +1,20 @@ +import { createApp } from "vue"; +import card from "./card.js"; +import card_back from "./card_back.js"; +import card_front from "./card_front.js"; +import editor_colors from "./editor_colors.js"; +import editor_details from "./editor_details.js"; +import editor_items from "./editor_items.js"; +import editor_items_item from "./editor_items_item.js"; +import editor_layout from "./layout.js"; + +const app = createApp(); +app.component("cardie-card", card); +app.component("cardie-card-front", card_front); +app.component("cardie-card-back", card_back); +app.component("cardie-editor-details", editor_details); +app.component("cardie-editor-layout", editor_layout); +app.component("cardie-editor-colors", editor_colors); +app.component("cardie-editor-items", editor_items); +app.component("cardie-editor-items-item", editor_items_item); +app.mount("#editor_main"); diff --git a/cardie/static/beta/editor_colors.js b/cardie/static/beta/editor_colors.js new file mode 100644 index 0000000..6649e39 --- /dev/null +++ b/cardie/static/beta/editor_colors.js @@ -0,0 +1,19 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + template: `
+

+ Colors +

+
+

Background color

+ +

Accent color

+ +

Text color

+ +
` +} diff --git a/cardie/static/beta/editor_details.js b/cardie/static/beta/editor_details.js new file mode 100644 index 0000000..522240d --- /dev/null +++ b/cardie/static/beta/editor_details.js @@ -0,0 +1,27 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + template: `
+

+ Details +

+
+ + +
` +} diff --git a/cardie/static/beta/editor_items.js b/cardie/static/beta/editor_items.js new file mode 100644 index 0000000..45c2607 --- /dev/null +++ b/cardie/static/beta/editor_items.js @@ -0,0 +1,21 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + template: ` +
+

+ Items +

+
+
+ +
+ +
+`, +}; diff --git a/cardie/static/beta/editor_items_item.js b/cardie/static/beta/editor_items_item.js new file mode 100644 index 0000000..fc2c9ea --- /dev/null +++ b/cardie/static/beta/editor_items_item.js @@ -0,0 +1,52 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store, menuOpen: false }; + }, + methods: { + changeType() { + if (this.item.value.type === "text") { + this.item.value.type = "url"; + } else { + this.item.value.type = "text"; + } + }, + }, + props: ["item"], + template: `
+
+

+ +

+ + + +
+
+ + + + +
+
+`, +}; diff --git a/cardie/static/beta/layout.js b/cardie/static/beta/layout.js new file mode 100644 index 0000000..4646476 --- /dev/null +++ b/cardie/static/beta/layout.js @@ -0,0 +1,37 @@ +import { store } from "./store.js"; + +export default { + data() { + return { store }; + }, + + template: `
+

+ Layout +

+
+
+ + + +
+
`, +} diff --git a/cardie/static/beta/store.js b/cardie/static/beta/store.js new file mode 100644 index 0000000..241d4e1 --- /dev/null +++ b/cardie/static/beta/store.js @@ -0,0 +1,125 @@ +import { reactive, watchEffect } from "vue"; + +/** + * @typedef LinkItem + * @type {object} + * @property {"url"} type + * @property {string} url + * @property {string} text + */ + +/** + * @typedef TextItem + * @type {object} + * @property {"text"} type + * @property {string} text + */ + +/** + * @typedef Item + * @type {object} + * @property {string} id + * @property {LinkItem | TextItem} value + * @property {string} icon + */ + +/** + * @typedef Store + * @type {object} + * @property {object} card + * @property {object} card.styles + * @property {string} card.styles.fontFamily + * @property {object} card.colors + * @property {string} card.colors.background + * @property {string} card.colors.accent + * @property {string} card.colors.text + * @property {object} card.front + * @property {string} card.front.title + * @property {string} card.front.subTitle + * @property {"left" | "center" | "right"} card.front.align + * @property {Item[]} card.items + * @property {(layout: "left" | "center" | "right") => void} changeLayout + * @property {(item: Item) => void} addItem + * @property {(id: string) => void} deleteItem + * @property {(id: string, value: LinkItem | TextItem) => void} updateItem + */ + +/** + * @return {Store} + */ +const defaultData = { + card: { + styles: { + fontFamily: "Noto Sans", + }, + colors: { + background: "#fff", + accent: "#000", + text: "#f0f", + }, + front: { + title: "Card Title", + subTitle: "Card Subtitle", + align: "center", + }, + items: [ + { + id: "cae2d2af-240e-46d7-b89c-ec84e28eb1a3", + value: { + text: "Hello, World!", + type: "text", + }, + + icon: "ph-globe", + }, + { + id: "348cf352-40cc-4138-afbb-b90b4082c4d4", + value: { + text: "My personal website!", + url: "https://example.com", + type: "url", + }, + icon: "ph-globe", + }, + ], + }, +}; +function storeFactory() { + const localRawData = localStorage.getItem("store"); + console.log("store "); + + const data = JSON.parse(localRawData || "") ?? defaultData; + return { + ...data, + changeLayout(layout) { + this.card.front.align = layout; + }, + addItem() { + this.card.items.push({ + icon: "ph-globe", + id: Math.random().toString(36).substr(2, 9), + value: { + text: "New item", + type: "text", + }, + }); + }, + deleteItem(id) { + this.card.items = this.card.items.filter((item) => item.id !== id); + }, + updateItem(id, value) { + this.card.items = this.card.items.map((item) => { + if (item.id === id) { + item.value = value; + } + return item; + }); + }, + }; +} + +export const store = reactive(storeFactory()); + +watchEffect(() => { + localStorage.setItem("store", JSON.stringify(store)); +}); diff --git a/cardie/static/main/card.css b/cardie/static/main/card.css index 293f228..81a855f 100644 --- a/cardie/static/main/card.css +++ b/cardie/static/main/card.css @@ -2,7 +2,7 @@ .card_card { margin: 10px; - + width: 600px; aspect-ratio: 1.75; @@ -198,4 +198,4 @@ border: none; background-color: none; color: rgb(64, 163, 255); -} \ No newline at end of file +}