make it easy to deploy yourself

This commit is contained in:
Dovi Cowan 2023-11-02 00:06:48 +00:00
parent 5ebcbb0ced
commit 17a21a6947
Signed by: dcowan
GPG key ID: CC4A4CB950D7E579
7 changed files with 252 additions and 36 deletions

2
.env
View file

@ -1 +1,3 @@
VITE_APPWRITE_ENDPOINT=https://api.fnukapps.com/v1
VITE_APPWRITE_PROJECT_ID=6524683fc8d947fe9a07
VITE_APPWRITE_DB_ID=tehillim-split

View file

@ -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.
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.

170
appwrite.json Normal file
View file

@ -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"
]
}
]
}
]
}

View file

@ -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);

View file

@ -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"],
{},

View file

@ -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());
}

View file

@ -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;
});
});
}
</script>
@ -149,7 +172,11 @@
Loading...
{:then list}
<h1 class="text-2xl">List {list.title}</h1>
<p>List split by {list.list_type=="perakim"?"perek":""}{list.list_type=="month"?"days of month":""}</p>
<p>
List split by {list.list_type == "perakim"
? "perek"
: ""}{list.list_type == "month" ? "days of month" : ""}
</p>
<br />
<Link class="text-blue-400" to="/list/{id}/members">Members</Link>
{#await teamDetails then team}