From e99d3c9354c89aed75683ef40a57ba32b72e8f1c Mon Sep 17 00:00:00 2001 From: h3nryc0ding Date: Fri, 5 Jan 2024 21:32:01 +0000 Subject: [PATCH] Frontend: home, chat, login and navigation added. --- README.md | 44 ++ frontend/package.json | 2 + frontend/pnpm-lock.yaml | 42 ++ frontend/schema.graphql | 531 +++++++++--------- frontend/src/app.html | 1 + frontend/src/lib/SiteFooter.svelte | 0 frontend/src/lib/SiteHeader.svelte | 46 ++ .../alert-dialog/alert-dialog-action.svelte | 21 + .../alert-dialog/alert-dialog-cancel.svelte | 21 + .../alert-dialog/alert-dialog-content.svelte | 28 + .../alert-dialog-description.svelte | 16 + .../alert-dialog/alert-dialog-footer.svelte | 16 + .../alert-dialog/alert-dialog-header.svelte | 13 + .../alert-dialog/alert-dialog-overlay.svelte | 21 + .../alert-dialog/alert-dialog-portal.svelte | 9 + .../ui/alert-dialog/alert-dialog-title.svelte | 14 + .../lib/components/ui/alert-dialog/index.ts | 40 ++ frontend/src/routes/+layout.svelte | 12 +- frontend/src/routes/+page.svelte | 142 ++--- frontend/src/routes/{ => chat}/+page.gql | 0 frontend/src/routes/chat/+page.svelte | 85 +++ frontend/src/routes/login/+page.svelte | 25 + frontend/tailwind.config.js | 3 +- 23 files changed, 774 insertions(+), 358 deletions(-) create mode 100644 frontend/src/lib/SiteFooter.svelte create mode 100644 frontend/src/lib/SiteHeader.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte create mode 100644 frontend/src/lib/components/ui/alert-dialog/index.ts rename frontend/src/routes/{ => chat}/+page.gql (100%) create mode 100644 frontend/src/routes/chat/+page.svelte create mode 100644 frontend/src/routes/login/+page.svelte diff --git a/README.md b/README.md index 8858c65..d931122 100644 --- a/README.md +++ b/README.md @@ -113,3 +113,47 @@ sudo iptables-restore < /etc/iptables/rules.v4 ``` [Credits](https://github.com/canonical/microk8s/issues/854#issuecomment-1716576495) + +# Welcome + +## What is this website about? + +This website is a place where I test out new concepts and technologies that interest me. While I don't focus on the +visual or responsive part of the website, I do aim to learn as much as possible from each project. + +## What is the technology stack? + +Here are the base frameworks used for this: + +- Backend: Spring Boot +- API: GraphQL +- Frontend: Sveltekit + +In the lower section, you will find the packages or dependencies used. + +## What's working? + +Currently, this machine is running in the Oracle Cloud on an always-free VM. I set up a microk8s cluster which features: + +- TLS certificate fetching via Let's Encrypt ACME +- SSR rendering with direct connection via service discovery +- Redis for temporary data + +As full-stack features, there is currently only the live chat. There is definitely more to come. + +## What's coming? + +There is a lot of stuff planned for this. + +Currently, the focus is set to: + +- OAuth 2 via Spring +- Remote Kubernetes rollout without SSH + +## Dependencies + +- Backend + - Netflix DGS +- Frontend + - Houdini GraphQL + - Shadcn Svelte \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 38478ff..c327bcf 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,6 +18,7 @@ "@sveltejs/adapter-node": "^2.0.2", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@tailwindcss/typography": "^0.5.10", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "autoprefixer": "^10.4.16", @@ -45,6 +46,7 @@ "clsx": "^2.0.0", "graphql-ws": "^5.14.3", "lucide-svelte": "^0.302.0", + "mode-watcher": "^0.1.2", "tailwind-merge": "^2.2.0", "tailwind-variants": "^0.1.19" } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index d1e1d1a..c0e59d6 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -17,6 +17,9 @@ dependencies: lucide-svelte: specifier: ^0.302.0 version: 0.302.0(svelte@4.2.8) + mode-watcher: + specifier: ^0.1.2 + version: 0.1.2(svelte@4.2.8) tailwind-merge: specifier: ^2.2.0 version: 2.2.0 @@ -37,6 +40,9 @@ devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.0.0 version: 3.0.1(svelte@4.2.8)(vite@5.0.10) + '@tailwindcss/typography': + specifier: ^0.5.10 + version: 0.5.10(tailwindcss@3.4.0) '@typescript-eslint/eslint-plugin': specifier: ^6.0.0 version: 6.15.0(@typescript-eslint/parser@6.15.0)(eslint@8.56.0)(typescript@5.3.3) @@ -1210,6 +1216,18 @@ packages: tslib: 2.6.2 dev: false + /@tailwindcss/typography@0.5.10(tailwindcss@3.4.0): + resolution: {integrity: sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.0 + dev: true + /@types/braces@3.0.4: resolution: {integrity: sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==} dev: true @@ -2780,6 +2798,14 @@ packages: p-locate: 5.0.0 dev: true + /lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -2893,6 +2919,14 @@ packages: ufo: 1.3.2 dev: true + /mode-watcher@0.1.2(svelte@4.2.8): + resolution: {integrity: sha512-XTdPCdqC3kqSvB+Q262Kor983YJkkB2Z3vj9uqg5IqKQpOdiz+xB99Jihp8sWbyM67drC7KKp0Nt5FzCypZi2g==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + svelte: 4.2.8 + dev: false + /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -3256,6 +3290,14 @@ packages: postcss: 8.4.32 dev: true + /postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + /postcss-selector-parser@6.0.13: resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} engines: {node: '>=4'} diff --git a/frontend/schema.graphql b/frontend/schema.graphql index 8ebc618..4e5199e 100644 --- a/frontend/schema.graphql +++ b/frontend/schema.graphql @@ -4,9 +4,7 @@ directive @external on FIELD_DEFINITION directive @key(fields: _FieldSet!) on INTERFACE | OBJECT -""" -Indicates an Input Object is a OneOf Input Object. -""" +"""Indicates an Input Object is a OneOf Input Object.""" directive @oneOf on INPUT_OBJECT directive @provides(fields: _FieldSet!) on FIELD_DEFINITION @@ -14,291 +12,290 @@ directive @provides(fields: _FieldSet!) on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION enum ErrorDetail { - """ - The deadline expired before the operation could complete. - - For operations that change the state of the system, this error - may be returned even if the operation has completed successfully. - For example, a successful response from a server could have been - delayed long enough for the deadline to expire. - - HTTP Mapping: 504 Gateway Timeout - Error Type: UNAVAILABLE - """ - DEADLINE_EXCEEDED - - """ - The server detected that the client is exhibiting a behavior that - might be generating excessive load. - - HTTP Mapping: 429 Too Many Requests or 420 Enhance Your Calm - Error Type: UNAVAILABLE - """ - ENHANCE_YOUR_CALM - - """ - The requested field is not found in the schema. - - This differs from `NOT_FOUND` in that `NOT_FOUND` should be used when a - query is valid, but is unable to return a result (if, for example, a - specific video id doesn't exist). `FIELD_NOT_FOUND` is intended to be - returned by the server to signify that the requested field is not known to exist. - This may be returned in lieu of failing the entire query. - See also `PERMISSION_DENIED` for cases where the - requested field is invalid only for the given user or class of users. - - HTTP Mapping: 404 Not Found - Error Type: BAD_REQUEST - """ - FIELD_NOT_FOUND - - """ - The client specified an invalid argument. - - Note that this differs from `FAILED_PRECONDITION`. - `INVALID_ARGUMENT` indicates arguments that are problematic - regardless of the state of the system (e.g., a malformed file name). - - HTTP Mapping: 400 Bad Request - Error Type: BAD_REQUEST - """ - INVALID_ARGUMENT - - """ - The provided cursor is not valid. - - The most common usage for this error is when a client is paginating - through a list that uses stateful cursors. In that case, the provided - cursor may be expired. - - HTTP Mapping: 404 Not Found - Error Type: NOT_FOUND - """ - INVALID_CURSOR - - """ - Unable to perform operation because a required resource is missing. - - Example: Client is attempting to refresh a list, but the specified - list is expired. This requires an action by the client to get a new list. - - If the user is simply trying GET a resource that is not found, - use the NOT_FOUND error type. FAILED_PRECONDITION.MISSING_RESOURCE - is to be used particularly when the user is performing an operation - that requires a particular resource to exist. - - HTTP Mapping: 400 Bad Request or 500 Internal Server Error - Error Type: FAILED_PRECONDITION - """ - MISSING_RESOURCE - - """ - Service Error. - - There is a problem with an upstream service. - - This may be returned if a gateway receives an unknown error from a service - or if a service is unreachable. - If a request times out which waiting on a response from a service, - `DEADLINE_EXCEEDED` may be returned instead. - If a service returns a more specific error Type, the specific error Type may - be returned instead. - - HTTP Mapping: 502 Bad Gateway - Error Type: UNAVAILABLE - """ - SERVICE_ERROR - - """ - Request failed due to network errors. - - HTTP Mapping: 503 Unavailable - Error Type: UNAVAILABLE - """ - TCP_FAILURE - - """ - Request throttled based on server concurrency limits. - - HTTP Mapping: 503 Unavailable - Error Type: UNAVAILABLE - """ - THROTTLED_CONCURRENCY - - """ - Request throttled based on server CPU limits - - HTTP Mapping: 503 Unavailable. - Error Type: UNAVAILABLE - """ - THROTTLED_CPU - - """ - The operation is not implemented or is not currently supported/enabled. - - HTTP Mapping: 501 Not Implemented - Error Type: BAD_REQUEST - """ - UNIMPLEMENTED - - """ - Unknown error. - - This error should only be returned when no other error detail applies. - If a client sees an unknown errorDetail, it will be interpreted as UNKNOWN. - - HTTP Mapping: 500 Internal Server Error - """ - UNKNOWN + """ + The deadline expired before the operation could complete. + + For operations that change the state of the system, this error + may be returned even if the operation has completed successfully. + For example, a successful response from a server could have been + delayed long enough for the deadline to expire. + + HTTP Mapping: 504 Gateway Timeout + Error Type: UNAVAILABLE + """ + DEADLINE_EXCEEDED + + """ + The server detected that the client is exhibiting a behavior that + might be generating excessive load. + + HTTP Mapping: 429 Too Many Requests or 420 Enhance Your Calm + Error Type: UNAVAILABLE + """ + ENHANCE_YOUR_CALM + + """ + The requested field is not found in the schema. + + This differs from `NOT_FOUND` in that `NOT_FOUND` should be used when a + query is valid, but is unable to return a result (if, for example, a + specific video id doesn't exist). `FIELD_NOT_FOUND` is intended to be + returned by the server to signify that the requested field is not known to exist. + This may be returned in lieu of failing the entire query. + See also `PERMISSION_DENIED` for cases where the + requested field is invalid only for the given user or class of users. + + HTTP Mapping: 404 Not Found + Error Type: BAD_REQUEST + """ + FIELD_NOT_FOUND + + """ + The client specified an invalid argument. + + Note that this differs from `FAILED_PRECONDITION`. + `INVALID_ARGUMENT` indicates arguments that are problematic + regardless of the state of the system (e.g., a malformed file name). + + HTTP Mapping: 400 Bad Request + Error Type: BAD_REQUEST + """ + INVALID_ARGUMENT + + """ + The provided cursor is not valid. + + The most common usage for this error is when a client is paginating + through a list that uses stateful cursors. In that case, the provided + cursor may be expired. + + HTTP Mapping: 404 Not Found + Error Type: NOT_FOUND + """ + INVALID_CURSOR + + """ + Unable to perform operation because a required resource is missing. + + Example: Client is attempting to refresh a list, but the specified + list is expired. This requires an action by the client to get a new list. + + If the user is simply trying GET a resource that is not found, + use the NOT_FOUND error type. FAILED_PRECONDITION.MISSING_RESOURCE + is to be used particularly when the user is performing an operation + that requires a particular resource to exist. + + HTTP Mapping: 400 Bad Request or 500 Internal Server Error + Error Type: FAILED_PRECONDITION + """ + MISSING_RESOURCE + + """ + Service Error. + + There is a problem with an upstream service. + + This may be returned if a gateway receives an unknown error from a service + or if a service is unreachable. + If a request times out which waiting on a response from a service, + `DEADLINE_EXCEEDED` may be returned instead. + If a service returns a more specific error Type, the specific error Type may + be returned instead. + + HTTP Mapping: 502 Bad Gateway + Error Type: UNAVAILABLE + """ + SERVICE_ERROR + + """ + Request failed due to network errors. + + HTTP Mapping: 503 Unavailable + Error Type: UNAVAILABLE + """ + TCP_FAILURE + + """ + Request throttled based on server concurrency limits. + + HTTP Mapping: 503 Unavailable + Error Type: UNAVAILABLE + """ + THROTTLED_CONCURRENCY + + """ + Request throttled based on server CPU limits + + HTTP Mapping: 503 Unavailable. + Error Type: UNAVAILABLE + """ + THROTTLED_CPU + + """ + The operation is not implemented or is not currently supported/enabled. + + HTTP Mapping: 501 Not Implemented + Error Type: BAD_REQUEST + """ + UNIMPLEMENTED + + """ + Unknown error. + + This error should only be returned when no other error detail applies. + If a client sees an unknown errorDetail, it will be interpreted as UNKNOWN. + + HTTP Mapping: 500 Internal Server Error + """ + UNKNOWN } enum ErrorType { - """ - Bad Request. - - There is a problem with the request. - Retrying the same request is not likely to succeed. - An example would be a query or argument that cannot be deserialized. - - HTTP Mapping: 400 Bad Request - """ - BAD_REQUEST - - """ - The operation was rejected because the system is not in a state - required for the operation's execution. For example, the directory - to be deleted is non-empty, an rmdir operation is applied to - a non-directory, etc. - - Service implementers can use the following guidelines to decide - between `FAILED_PRECONDITION` and `UNAVAILABLE`: - - - Use `UNAVAILABLE` if the client can retry just the failing call. - - Use `FAILED_PRECONDITION` if the client should not retry until - the system state has been explicitly fixed. E.g., if an "rmdir" - fails because the directory is non-empty, `FAILED_PRECONDITION` - should be returned since the client should not retry unless - the files are deleted from the directory. - - HTTP Mapping: 400 Bad Request or 500 Internal Server Error - """ - FAILED_PRECONDITION - - """ - Internal error. - - An unexpected internal error was encountered. This means that some - invariants expected by the underlying system have been broken. - This error code is reserved for serious errors. - - HTTP Mapping: 500 Internal Server Error - """ - INTERNAL - - """ - The requested entity was not found. - - This could apply to a resource that has never existed (e.g. bad resource id), - or a resource that no longer exists (e.g. cache expired.) - - Note to server developers: if a request is denied for an entire class - of users, such as gradual feature rollout or undocumented allowlist, - `NOT_FOUND` may be used. If a request is denied for some users within - a class of users, such as user-based access control, `PERMISSION_DENIED` - must be used. - - HTTP Mapping: 404 Not Found - """ - NOT_FOUND - - """ - The caller does not have permission to execute the specified - operation. - - `PERMISSION_DENIED` must not be used for rejections - caused by exhausting some resource or quota. - `PERMISSION_DENIED` must not be used if the caller - cannot be identified (use `UNAUTHENTICATED` - instead for those errors). - - This error Type does not imply the - request is valid or the requested entity exists or satisfies - other pre-conditions. - - HTTP Mapping: 403 Forbidden - """ - PERMISSION_DENIED - - """ - The request does not have valid authentication credentials. - - This is intended to be returned only for routes that require - authentication. - - HTTP Mapping: 401 Unauthorized - """ - UNAUTHENTICATED - - """ - Currently Unavailable. - - The service is currently unavailable. This is most likely a - transient condition, which can be corrected by retrying with - a backoff. - - HTTP Mapping: 503 Unavailable - """ - UNAVAILABLE - - """ - Unknown error. - - For example, this error may be returned when - an error code received from another address space belongs to - an error space that is not known in this address space. Also - errors raised by APIs that do not return enough error information - may be converted to this error. - - If a client sees an unknown errorType, it will be interpreted as UNKNOWN. - Unknown errors MUST NOT trigger any special behavior. These MAY be treated - by an implementation as being equivalent to INTERNAL. - - When possible, a more specific error should be provided. - - HTTP Mapping: 520 Unknown Error - """ - UNKNOWN + """ + Bad Request. + + There is a problem with the request. + Retrying the same request is not likely to succeed. + An example would be a query or argument that cannot be deserialized. + + HTTP Mapping: 400 Bad Request + """ + BAD_REQUEST + + """ + The operation was rejected because the system is not in a state + required for the operation's execution. For example, the directory + to be deleted is non-empty, an rmdir operation is applied to + a non-directory, etc. + + Service implementers can use the following guidelines to decide + between `FAILED_PRECONDITION` and `UNAVAILABLE`: + + - Use `UNAVAILABLE` if the client can retry just the failing call. + - Use `FAILED_PRECONDITION` if the client should not retry until + the system state has been explicitly fixed. E.g., if an "rmdir" + fails because the directory is non-empty, `FAILED_PRECONDITION` + should be returned since the client should not retry unless + the files are deleted from the directory. + + HTTP Mapping: 400 Bad Request or 500 Internal Server Error + """ + FAILED_PRECONDITION + + """ + Internal error. + + An unexpected internal error was encountered. This means that some + invariants expected by the underlying system have been broken. + This error code is reserved for serious errors. + + HTTP Mapping: 500 Internal Server Error + """ + INTERNAL + + """ + The requested entity was not found. + + This could apply to a resource that has never existed (e.g. bad resource id), + or a resource that no longer exists (e.g. cache expired.) + + Note to server developers: if a request is denied for an entire class + of users, such as gradual feature rollout or undocumented allowlist, + `NOT_FOUND` may be used. If a request is denied for some users within + a class of users, such as user-based access control, `PERMISSION_DENIED` + must be used. + + HTTP Mapping: 404 Not Found + """ + NOT_FOUND + + """ + The caller does not have permission to execute the specified + operation. + + `PERMISSION_DENIED` must not be used for rejections + caused by exhausting some resource or quota. + `PERMISSION_DENIED` must not be used if the caller + cannot be identified (use `UNAUTHENTICATED` + instead for those errors). + + This error Type does not imply the + request is valid or the requested entity exists or satisfies + other pre-conditions. + + HTTP Mapping: 403 Forbidden + """ + PERMISSION_DENIED + + """ + The request does not have valid authentication credentials. + + This is intended to be returned only for routes that require + authentication. + + HTTP Mapping: 401 Unauthorized + """ + UNAUTHENTICATED + + """ + Currently Unavailable. + + The service is currently unavailable. This is most likely a + transient condition, which can be corrected by retrying with + a backoff. + + HTTP Mapping: 503 Unavailable + """ + UNAVAILABLE + + """ + Unknown error. + + For example, this error may be returned when + an error code received from another address space belongs to + an error space that is not known in this address space. Also + errors raised by APIs that do not return enough error information + may be converted to this error. + + If a client sees an unknown errorType, it will be interpreted as UNKNOWN. + Unknown errors MUST NOT trigger any special behavior. These MAY be treated + by an implementation as being equivalent to INTERNAL. + + When possible, a more specific error should be provided. + + HTTP Mapping: 520 Unknown Error + """ + UNKNOWN } type Message { - creator: String! - id: ID! - text: String! - timestamp: String! + creator: String! + id: ID! + text: String! + timestamp: String! } input MessageInput { - creator: String! - text: String! + creator: String! + text: String! } type Mutation { - messageSend(input: MessageInput!): Message! + messageSend(input: MessageInput!): Message! } type Query { - _service: _Service! - messages: [Message!]! + _service: _Service! + messages: [Message!]! } type Subscription { - messageSent: Message! + messageSent: Message! } -""" -""" +"""""" scalar _FieldSet type _Service { - sdl: String! + sdl: String! } diff --git a/frontend/src/app.html b/frontend/src/app.html index f273cc5..0c70a0f 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -3,6 +3,7 @@ + %sveltekit.head% diff --git a/frontend/src/lib/SiteFooter.svelte b/frontend/src/lib/SiteFooter.svelte new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/lib/SiteHeader.svelte b/frontend/src/lib/SiteHeader.svelte new file mode 100644 index 0000000..5512169 --- /dev/null +++ b/frontend/src/lib/SiteHeader.svelte @@ -0,0 +1,46 @@ + + +
+
+ +
+ +
+
+
diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte new file mode 100644 index 0000000..723052b --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte @@ -0,0 +1,21 @@ + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte new file mode 100644 index 0000000..09af9bd --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte @@ -0,0 +1,21 @@ + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte new file mode 100644 index 0000000..7e2d881 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte new file mode 100644 index 0000000..f4af7fd --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte new file mode 100644 index 0000000..da4f517 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte @@ -0,0 +1,16 @@ + + +
+ +
diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte new file mode 100644 index 0000000..40dfb92 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte new file mode 100644 index 0000000..1c6afd2 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte @@ -0,0 +1,21 @@ + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte new file mode 100644 index 0000000..347119a --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte new file mode 100644 index 0000000..fb4dc59 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte @@ -0,0 +1,14 @@ + + + + + diff --git a/frontend/src/lib/components/ui/alert-dialog/index.ts b/frontend/src/lib/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..0cf3d72 --- /dev/null +++ b/frontend/src/lib/components/ui/alert-dialog/index.ts @@ -0,0 +1,40 @@ +import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; + +const Root = AlertDialogPrimitive.Root; +const Trigger = AlertDialogPrimitive.Trigger; + +import Title from './alert-dialog-title.svelte'; +import Action from './alert-dialog-action.svelte'; +import Cancel from './alert-dialog-cancel.svelte'; +import Portal from './alert-dialog-portal.svelte'; +import Footer from './alert-dialog-footer.svelte'; +import Header from './alert-dialog-header.svelte'; +import Overlay from './alert-dialog-overlay.svelte'; +import Content from './alert-dialog-content.svelte'; +import Description from './alert-dialog-description.svelte'; + +export { + Root, + Title, + Action, + Cancel, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + // + Root as AlertDialog, + Title as AlertDialogTitle, + Action as AlertDialogAction, + Cancel as AlertDialogCancel, + Portal as AlertDialogPortal, + Footer as AlertDialogFooter, + Header as AlertDialogHeader, + Trigger as AlertDialogTrigger, + Overlay as AlertDialogOverlay, + Content as AlertDialogContent, + Description as AlertDialogDescription +}; diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index bf1faec..d841503 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -1,5 +1,8 @@ @@ -11,4 +14,11 @@ - + +
+ +
+ +
+ +
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 1de02f6..f36674f 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,89 +1,53 @@ - - - - - - Please enter your username - -
- -
- - - - -
-
-
-
- -
- {#each $AllMessage.data?.messages || [] as message (message.id)} - -
-
-

{message.text}

-

-{message.creator} at {message.timestamp}

-
-
- {/each} -
-
- -
-
- - -
-
-
+
+

Welcome

+

What is this website about?

+

+ This website is a place where I test out new concepts and technologies that interest me. While I + don't focus on the visual or responsive part of the website, I do aim to learn as much as + possible from each project. +

+

What is the technology stack?

+

Here are the base frameworks used for this:

+
    +
  • Backend: Spring Boot
  • +
  • API: GraphQL
  • +
  • Frontend: Sveltekit
  • +
+

In the lower section, you will find the packages or dependencies used.

+

What's working?

+

+ Currently, this machine is running in the Oracle Cloud on an always-free VM. I set up a microk8s + cluster which features: +

+
    +
  • TLS certificate fetching via Let's Encrypt ACME
  • +
  • SSR rendering with direct connection via service discovery
  • +
  • Redis for temporary data
  • +
+

+ As full-stack features, there is currently only the live chat. There is definitely more to come. +

+

What's coming?

+

There is a lot of stuff planned for this.

+

Currently, the focus is set to:

+
    +
  • OAuth 2 via Spring
  • +
  • Remote Kubernetes rollout without SSH
  • +
+

Dependencies

+
    +
  • + Backend +
      +
    • Netflix DGS
    • +
    +
  • +
  • + Frontend +
      +
    • Houdini GraphQL
    • +
    • Shadcn Svelte
    • +
    +
  • +
+
diff --git a/frontend/src/routes/+page.gql b/frontend/src/routes/chat/+page.gql similarity index 100% rename from frontend/src/routes/+page.gql rename to frontend/src/routes/chat/+page.gql diff --git a/frontend/src/routes/chat/+page.svelte b/frontend/src/routes/chat/+page.svelte new file mode 100644 index 0000000..a1d1691 --- /dev/null +++ b/frontend/src/routes/chat/+page.svelte @@ -0,0 +1,85 @@ + + + + + + Please enter your username + +
+ +
+ + + + +
+
+
+
+ +
+ {#each $AllMessage.data?.messages || [] as message (message.id)} + +
+
+

{message.text}

+

+ {message.creator} at {new Date(message.timestamp).toLocaleString('en-US')} +

+
+
+ {/each} +
+
+ +
+
+ + +
+
+
diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte new file mode 100644 index 0000000..3c3087d --- /dev/null +++ b/frontend/src/routes/login/+page.svelte @@ -0,0 +1,25 @@ + + + + + + + Under Construction + + + + This feature is currently under development. Although you cannot log in at the moment, this + functionality will be available in the future. Stay tuned for updates! + + + + + + + + + diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 38fb24e..6d6524f 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -58,7 +58,8 @@ const config = { sans: [...fontFamily.sans] } } - } + }, + plugins: [require('@tailwindcss/typography')] }; export default config;