diff --git a/.env b/.env index e6b8905..d355c69 100644 --- a/.env +++ b/.env @@ -1 +1,3 @@ +VITE_APPWRITE_ENDPOINT=https://api.fnukapps.com/v1 +VITE_APPWRITE_PROJECT_ID=6524683fc8d947fe9a07 VITE_APPWRITE_DB_ID=tehillim-split \ No newline at end of file diff --git a/README.md b/README.md index 6f3885b..c54a127 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,19 @@ This is a web application to split Sefer Tehillim between a group of people. You Currently live at https://tehillim-split.dovicowan.dev -Tehillim Split is build on Appwrite BaaS. Config files and setting your own Appwrite endpoint coming soon, but for now you can set your endpoint in `src/lib/appwrite.js` and your project ID as env `VITE_APPWRITE_DB_ID`. - -Frontend in Svelte, run `npm install` + `npm run dev` to run locally. - ## Github -The Github repo is a mirror of the repo on my self-hosted Git server at https://git.fnukhosting.net/dcowan/tehillim-split. \ No newline at end of file +The Github repo is a mirror of the repo on my self-hosted Git server at https://git.fnukhosting.net/dcowan/tehillim-split. + +## Building it yourself +Tehillim Split is built on top of Appwrite BaaS and the frontend is Svelte+Vite. To host it yourself, you'll either need your own Appwrite self hosted instance, or you can use [Appwrite Cloud](cloud.appwrite.io). + +### Deploy to Appwrite +1. Set up the Appwrite CLI, and connect it to your Appwrite instance with `$ appwrite login` +2. Create a new Project with `$ appwrite init project`. +3. Deploy the DB with `$ appwrite deploy collection`. Select all Collections. +4. Update `VITE_APPWRITE_ENDPOINT` and `VITE_APPWRITE_PROJECT_ID` in `.env`. + +### Deploy frontend +`npm install` + `npm run dev` / `npm run build`. + +**NOTICE:** You need to add a platform from the Appwrite Console when deploying to production, otherwise you'll get a CORS error. Wildcards are not supported in the Hostname field. \ No newline at end of file diff --git a/appwrite.json b/appwrite.json new file mode 100644 index 0000000..d11eb3e --- /dev/null +++ b/appwrite.json @@ -0,0 +1,170 @@ +{ + "projectId": "6524683fc8d947fe9a07", + "projectName": "Tehillim Split", + "databases": [ + { + "$id": "tehillim-split", + "name": "tehillim-split", + "$createdAt": "2023-10-11T14:08:05.106+00:00", + "$updatedAt": "2023-10-11T14:08:05.106+00:00", + "enabled": true + } + ], + "collections": [ + { + "$id": "lists", + "$permissions": [ + "create(\"users\")" + ], + "databaseId": "tehillim-split", + "name": "Lists", + "enabled": true, + "documentSecurity": true, + "attributes": [ + { + "key": "title", + "type": "string", + "status": "available", + "error": "", + "required": true, + "array": false, + "size": 1000, + "default": null + }, + { + "key": "require_logged_in", + "type": "boolean", + "status": "available", + "error": "", + "required": false, + "array": false, + "default": false + }, + { + "key": "owner_id", + "type": "string", + "status": "available", + "error": "", + "required": true, + "array": false, + "size": 40, + "default": null + }, + { + "key": "list_type", + "type": "string", + "status": "available", + "error": "", + "required": true, + "array": false, + "elements": [ + "perakim", + "month" + ], + "format": "enum", + "default": null + } + ], + "indexes": [ + { + "key": "require_logged_in", + "type": "key", + "status": "available", + "error": "", + "attributes": [ + "require_logged_in" + ], + "orders": [ + "ASC" + ] + } + ] + }, + { + "$id": "perakim", + "$permissions": [ + "create(\"users\")", + "read(\"users\")" + ], + "databaseId": "tehillim-split", + "name": "Perakim", + "enabled": true, + "documentSecurity": true, + "attributes": [ + { + "key": "list_id", + "type": "string", + "status": "available", + "error": "", + "required": true, + "array": false, + "size": 50, + "default": null + }, + { + "key": "perek", + "type": "integer", + "status": "available", + "error": "", + "required": true, + "array": false, + "min": 1, + "max": 150, + "default": null + }, + { + "key": "taken", + "type": "boolean", + "status": "available", + "error": "", + "required": false, + "array": false, + "default": false + }, + { + "key": "completed", + "type": "boolean", + "status": "available", + "error": "", + "required": false, + "array": false, + "default": false + }, + { + "key": "taken_by", + "type": "string", + "status": "available", + "error": "", + "required": false, + "array": false, + "size": 50, + "default": null + }, + { + "key": "taken_by_name", + "type": "string", + "status": "available", + "error": "", + "required": false, + "array": false, + "size": 800, + "default": null + } + ], + "indexes": [ + { + "key": "list_id", + "type": "key", + "status": "available", + "error": "", + "attributes": [ + "list_id" + ], + "orders": [ + "ASC" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/lib/appwrite.js b/src/lib/appwrite.js index 55e20e0..4f46deb 100644 --- a/src/lib/appwrite.js +++ b/src/lib/appwrite.js @@ -4,8 +4,8 @@ import { navigate } from 'svelte-navigator'; const appwrite = new Client(); appwrite - .setEndpoint("https://api.fnukapps.com/v1") - .setProject("6524683fc8d947fe9a07") + .setEndpoint(import.meta.env.VITE_APPWRITE_ENDPOINT) + .setProject(import.meta.env.VITE_APPWRITE_PROJECT_ID) export const account = new Account(appwrite); diff --git a/src/routes/Lists/ListCreate.svelte b/src/routes/Lists/ListCreate.svelte index 52bbe04..d0ca594 100644 --- a/src/routes/Lists/ListCreate.svelte +++ b/src/routes/Lists/ListCreate.svelte @@ -21,7 +21,7 @@ e.preventDefault(); database - .createDocument("tehillim-split", "lists", ID.unique(), { + .createDocument(import.meta.env.VITE_APPWRITE_DB_ID, "lists", ID.unique(), { title: listname, require_logged_in: !!requireLoggedIn, owner_id: loggedInUser["$id"], @@ -42,7 +42,7 @@ database .updateDocument( - "tehillim-split", + import.meta.env.VITE_APPWRITE_DB_ID, "lists", r["$id"], {}, diff --git a/src/routes/Lists/ListMembers.svelte b/src/routes/Lists/ListMembers.svelte index 7d7a012..7f52d86 100644 --- a/src/routes/Lists/ListMembers.svelte +++ b/src/routes/Lists/ListMembers.svelte @@ -12,7 +12,11 @@ export let id; - let list = database.getDocument("tehillim-split", "lists", id); + let list = database.getDocument( + import.meta.env.VITE_APPWRITE_DB_ID, + "lists", + id, + ); let members = teams.listMemberships(id); const rolesIndex = (user, role) => { @@ -42,7 +46,10 @@ email, undefined, undefined, - window.location.protocol + "//" + window.location.host + "/accept_list_invitation", + window.location.protocol + + "//" + + window.location.host + + "/accept_list_invitation", ) .then(() => getData()); } diff --git a/src/routes/Lists/ListView.svelte b/src/routes/Lists/ListView.svelte index be05da0..10b6cd5 100644 --- a/src/routes/Lists/ListView.svelte +++ b/src/routes/Lists/ListView.svelte @@ -9,7 +9,11 @@ let elementsNumbers = 0; - let list = database.getDocument("tehillim-split", "lists", id); + let list = database.getDocument( + import.meta.env.VITE_APPWRITE_DB_ID, + "lists", + id, + ); list.then((r) => { if (r.list_type == "perakim") elementsNumbers = 151; @@ -17,7 +21,9 @@ }); let perakim = []; let perakimPromise = database - .listDocuments("tehillim-split", "perakim", [Query.equal("list_id", [id])]) + .listDocuments(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", [ + Query.equal("list_id", [id]), + ]) .then((r) => { perakim = r.documents; }); @@ -43,7 +49,7 @@ console.log(perek); database .createDocument( - "tehillim-split", + import.meta.env.VITE_APPWRITE_DB_ID, "perakim", ID.unique(), { @@ -60,7 +66,7 @@ ) .then(() => { perakimPromise = database - .listDocuments("tehillim-split", "perakim", [ + .listDocuments(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", [ Query.equal("list_id", [id]), ]) .then((r) => { @@ -74,18 +80,23 @@ if (newTitle !== "") { database - .updateDocument("tehillim-split", "lists", id, { + .updateDocument(import.meta.env.VITE_APPWRITE_DB_ID, "lists", id, { title: newTitle, }) .then( - () => (list = database.getDocument("tehillim-split", "lists", id)), + () => + (list = database.getDocument( + import.meta.env.VITE_APPWRITE_DB_ID, + "lists", + id, + )), ); } } function deleteList() { database - .deleteDocument("tehillim-split", "lists", id) + .deleteDocument(import.meta.env.VITE_APPWRITE_DB_ID, "lists", id) .then(() => teams.delete(id).then(() => navigate("/", {}))); } @@ -93,12 +104,17 @@ let perekDBId = perakim[perekIndex(perek)]["$id"]; database - .updateDocument("tehillim-split", "perakim", perekDBId, { - completed: true, - }) + .updateDocument( + import.meta.env.VITE_APPWRITE_DB_ID, + "perakim", + perekDBId, + { + completed: true, + }, + ) .then(() => { perakimPromise = database - .listDocuments("tehillim-split", "perakim", [ + .listDocuments(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", [ Query.equal("list_id", [id]), ]) .then((r) => { @@ -111,12 +127,17 @@ let perekDBId = perakim[perekIndex(perek)]["$id"]; database - .updateDocument("tehillim-split", "perakim", perekDBId, { - completed: false, - }) + .updateDocument( + import.meta.env.VITE_APPWRITE_DB_ID, + "perakim", + perekDBId, + { + completed: false, + }, + ) .then(() => { perakimPromise = database - .listDocuments("tehillim-split", "perakim", [ + .listDocuments(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", [ Query.equal("list_id", [id]), ]) .then((r) => { @@ -128,15 +149,17 @@ function untakePerek(perek) { let perekDBId = perakim[perekIndex(perek)]["$id"]; - database.deleteDocument("tehillim-split", "perakim", perekDBId).then(() => { - perakimPromise = database - .listDocuments("tehillim-split", "perakim", [ - Query.equal("list_id", [id]), - ]) - .then((r) => { - perakim = r.documents; - }); - }); + database + .deleteDocument(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", perekDBId) + .then(() => { + perakimPromise = database + .listDocuments(import.meta.env.VITE_APPWRITE_DB_ID, "perakim", [ + Query.equal("list_id", [id]), + ]) + .then((r) => { + perakim = r.documents; + }); + }); } @@ -149,7 +172,11 @@ Loading... {:then list}

List {list.title}

-

List split by {list.list_type=="perakim"?"perek":""}{list.list_type=="month"?"days of month":""}

+

+ List split by {list.list_type == "perakim" + ? "perek" + : ""}{list.list_type == "month" ? "days of month" : ""} +


Members {#await teamDetails then team}