diff --git a/package-lock.json b/package-lock.json
index 61530ef93d..1201290435 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.1",
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
+ "@analytics/google-tag-manager": "^0.5.3",
"@appwrite.io/pink": "^0.0.4",
"@aw-labs/appwrite-console": "^13.1.0",
"@popperjs/core": "^2.11.6",
@@ -19,6 +20,7 @@
"logrocket": "^3.0.1",
"pretty-bytes": "^6.1.0",
"prismjs": "^1.29.0",
+ "svelte-confetti": "^1.2.2",
"tippy.js": "^6.3.7",
"web-vitals": "^3.1.1"
},
@@ -113,6 +115,11 @@
"resolved": "https://registry.npmjs.org/@analytics/google-analytics/-/google-analytics-1.0.5.tgz",
"integrity": "sha512-I/yfiCVQo8AeT72KPa6z571LJKDbLdm4ntDqOHiE2Xehw9UjKcXQWiKTHL1/nfOOiekfpLf/6rFS5P6dQ0vImw=="
},
+ "node_modules/@analytics/google-tag-manager": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@analytics/google-tag-manager/-/google-tag-manager-0.5.3.tgz",
+ "integrity": "sha512-hk9cQtccAA48y3yP7wZ7k0ugi7qqi4dGB/w8d+hXwnPbo52MNu07ZtclL94S4GCb2vfVPfUgGz8vpuYBUO1xZw=="
+ },
"node_modules/@analytics/localstorage-utils": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/@analytics/localstorage-utils/-/localstorage-utils-0.1.8.tgz",
@@ -7973,6 +7980,24 @@
"svelte": "^3.55.0"
}
},
+ "node_modules/svelte-check/node_modules/typescript": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+ "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
+ "node_modules/svelte-confetti": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/svelte-confetti/-/svelte-confetti-1.2.2.tgz",
+ "integrity": "sha512-LkvWO732jRNmYykWi0IOK7xoBX241p+p+tC7Ef1EcO3TK9b9lpB/vYqKkcwVya+onG2SgQsX2g+JVbVKxq5ixQ=="
+ },
"node_modules/svelte-hmr": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
diff --git a/package.json b/package.json
index 0d0865856e..f10776a936 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
},
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
+ "@analytics/google-tag-manager": "^0.5.3",
"@appwrite.io/pink": "^0.0.4",
"@aw-labs/appwrite-console": "^13.1.0",
"@popperjs/core": "^2.11.6",
@@ -30,6 +31,7 @@
"logrocket": "^3.0.1",
"pretty-bytes": "^6.1.0",
"prismjs": "^1.29.0",
+ "svelte-confetti": "^1.2.2",
"tippy.js": "^6.3.7",
"web-vitals": "^3.1.1"
},
diff --git a/src/app.html b/src/app.html
index 994a0b038d..3a25d1151b 100644
--- a/src/app.html
+++ b/src/app.html
@@ -43,6 +43,8 @@
+
+
%sveltekit.head%
diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts
index c4324b9704..66a0181404 100644
--- a/src/lib/actions/analytics.ts
+++ b/src/lib/actions/analytics.ts
@@ -1,7 +1,8 @@
import { page } from '$app/stores';
import { user } from '$lib/stores/user';
-import { ENV, MODE, VARS } from '$lib/system';
+import { ENV, MODE, VARS, isCloud } from '$lib/system';
import googleAnalytics from '@analytics/google-analytics';
+import googleTagManager from '@analytics/google-tag-manager';
import { AppwriteException } from '@aw-labs/appwrite-console';
import Analytics from 'analytics';
import { get } from 'svelte/store';
@@ -11,7 +12,14 @@ const analytics = Analytics({
plugins: [
googleAnalytics({
measurementIds: [VARS.GOOGLE_ANALYTICS || 'G-R4YJ9JN8L4']
- })
+ }),
+ ...(isCloud
+ ? [
+ googleTagManager({
+ containerId: [VARS.GOOGLE_TAG || 'GTM-P3T9TBV']
+ })
+ ]
+ : [])
]
});
diff --git a/src/lib/elements/forms/button.svelte b/src/lib/elements/forms/button.svelte
index 27764b2a3e..7895f7e4a6 100644
--- a/src/lib/elements/forms/button.svelte
+++ b/src/lib/elements/forms/button.svelte
@@ -3,6 +3,7 @@
export let submit = false;
export let secondary = false;
+ export let github = false;
export let text = false;
export let danger = false;
export let disabled = false;
@@ -38,6 +39,7 @@
class="button"
class:is-only-icon={round}
class:is-secondary={secondary}
+ class:is-github={github}
class:is-text={text}
class:is-danger={danger}
class:is-full-width={fullWidth}
@@ -53,6 +55,7 @@
class="button"
class:is-only-icon={round}
class:is-secondary={secondary}
+ class:is-github={github}
class:is-danger={danger}
class:is-text={text}
class:is-full-width={fullWidth}
@@ -62,3 +65,17 @@
{/if}
+
+
diff --git a/src/lib/images/appwrite-cloud.svg b/src/lib/images/appwrite-cloud.svg
new file mode 100644
index 0000000000..c7b7a06942
--- /dev/null
+++ b/src/lib/images/appwrite-cloud.svg
@@ -0,0 +1,22 @@
+
diff --git a/src/lib/images/login/cloud-1.svg b/src/lib/images/login/cloud-1.svg
new file mode 100644
index 0000000000..a56f11b0ab
--- /dev/null
+++ b/src/lib/images/login/cloud-1.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/lib/images/login/cloud-2.svg b/src/lib/images/login/cloud-2.svg
new file mode 100644
index 0000000000..f11896e563
--- /dev/null
+++ b/src/lib/images/login/cloud-2.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/lib/images/login/cloud-bg-mobile.svg b/src/lib/images/login/cloud-bg-mobile.svg
new file mode 100644
index 0000000000..063ca22016
--- /dev/null
+++ b/src/lib/images/login/cloud-bg-mobile.svg
@@ -0,0 +1,626 @@
+
diff --git a/src/lib/images/login/cloud-bg.svg b/src/lib/images/login/cloud-bg.svg
new file mode 100644
index 0000000000..f4b555694f
--- /dev/null
+++ b/src/lib/images/login/cloud-bg.svg
@@ -0,0 +1,632 @@
+
diff --git a/src/lib/layout/header.svelte b/src/lib/layout/header.svelte
index 88a9a0b4b6..1b8e7863ed 100644
--- a/src/lib/layout/header.svelte
+++ b/src/lib/layout/header.svelte
@@ -5,24 +5,25 @@
DropList,
DropListItem,
DropListLink,
- FeedbackGeneral
+ FeedbackGeneral,
+ FeedbackNPS
} from '$lib/components';
- import { app, feedback } from '$lib/stores/app';
- import { user } from '$lib/stores/user';
- import { organizationList, organization, newOrgModal } from '$lib/stores/organization';
import AppwriteLogo from '$lib/images/appwrite-gray-light.svg';
- import LightMode from '$lib/images/mode/light-mode.svg';
import DarkMode from '$lib/images/mode/dark-mode.svg';
+ import LightMode from '$lib/images/mode/light-mode.svg';
import SystemMode from '$lib/images/mode/system-mode.svg';
- import { FeedbackNPS } from '$lib/components';
+ import { app, feedback } from '$lib/stores/app';
+ import { newOrgModal, organization, organizationList } from '$lib/stores/organization';
+ import { user } from '$lib/stores/user';
- let showFeedback = false;
- import { slide } from 'svelte/transition';
+ import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { Submit, trackEvent } from '$lib/actions/analytics';
import { sdkForConsole } from '$lib/stores/sdk';
- import { goto } from '$app/navigation';
+ import { slide } from 'svelte/transition';
+ import { isCloud } from '$lib/system';
+ let showFeedback = false;
let showDropdown = false;
let droplistElement: HTMLDivElement;
@@ -52,6 +53,17 @@
$: if (showDropdown) {
trackEvent('click_menu_dropdown');
}
+
+ const slideFade: typeof slide = (node, options) => {
+ const slideTrans = slide(node, options);
+ return {
+ ...slideTrans,
+ css: (t, u) => `
+ ${slideTrans.css(t, u)};
+ opacity: ${t};
+ `
+ };
+ };
@@ -113,7 +125,7 @@
{#if showDropdown}
+ transition:slideFade={{ duration: 150 }}>
{#if $organizationList?.total}
+ {#if isCloud}
+
+ {/if}
{/if}
{/if}
+
+
diff --git a/src/lib/layout/notifications.svelte b/src/lib/layout/notifications.svelte
index 2027027997..b5ea496b59 100644
--- a/src/lib/layout/notifications.svelte
+++ b/src/lib/layout/notifications.svelte
@@ -26,4 +26,12 @@
right: 24px;
z-index: 1000;
}
+
+ @media (max-width: 512px) {
+ section {
+ top: calc(var(--main-header-height) + 16px);
+ right: 16px;
+ left: 16px;
+ }
+ }
diff --git a/src/lib/layout/unauthenticated.svelte b/src/lib/layout/unauthenticated.svelte
index e2470d309a..3f4ebff5f0 100644
--- a/src/lib/layout/unauthenticated.svelte
+++ b/src/lib/layout/unauthenticated.svelte
@@ -1,10 +1,17 @@
-
-
-
-
+
-
-
- {#if $app.themeInUse === 'dark'}
-

- {:else}
-

- {/if}
-
+ Now in public beta
+
+
+
+
+
Integrate with your favourite technologies
+
+ {#each technologies as tech}
+ -
+
+
+ {/each}
+
+
+
+
+ {:else}
+
+
+
+
+
+
+
+ {#if $app.themeInUse === 'dark'}
+

+ {:else}
+

+ {/if}
+
-
-
-
-
-
Integrate with your favourite technologies
-
- {#each technologies as tech}
- -
-
-
- {/each}
-
-
-
-
-
-
+
+
+
Integrate with your favourite technologies
+
+ {#each technologies as tech}
+ -
+
+
+ {/each}
+
+
+
+
+ {/if}
+
+
+ {#if isCloud}
+
+
+
+
+
+ {/if}
+
-
-
+
+ {#if isCloud}
+
+
+ {/if}
+
+
+
@@ -83,12 +178,181 @@
-
-
-
-
-
-
+
+
diff --git a/src/lib/stores/windowFocus.ts b/src/lib/stores/windowFocus.ts
new file mode 100644
index 0000000000..b0c28abca4
--- /dev/null
+++ b/src/lib/stores/windowFocus.ts
@@ -0,0 +1,29 @@
+import { readable, type Readable } from 'svelte/store';
+
+function isCurrentWindowFocused(): boolean {
+ if (!window) return false;
+ if (!window.document) return false;
+ if (typeof window.document.hasFocus !== 'function') return false;
+
+ return window.document.hasFocus();
+}
+
+export function windowFocusStore(): Readable
{
+ const visibility = readable(isCurrentWindowFocused(), (set) => {
+ function handler() {
+ set(isCurrentWindowFocused());
+ }
+
+ if (window) {
+ window.addEventListener('focus', handler);
+ window.addEventListener('blur', handler);
+
+ return () => {
+ window.removeEventListener('focus', handler);
+ window.removeEventListener('blur', handler);
+ };
+ }
+ });
+
+ return visibility;
+}
diff --git a/src/lib/system.ts b/src/lib/system.ts
index 596e4faca8..9847882851 100644
--- a/src/lib/system.ts
+++ b/src/lib/system.ts
@@ -10,7 +10,8 @@ export const VARS = {
| undefined,
CONSOLE_MODE: import.meta.env?.VITE_CONSOLE_MODE?.toString() as string | undefined,
VERCEL_ENV: import.meta.env?.VITE_VERCEL_ENV?.toString() as string | undefined,
- GOOGLE_ANALYTICS: import.meta.env?.VITE_GA_PROJECT?.toString() as string | undefined
+ GOOGLE_ANALYTICS: import.meta.env?.VITE_GA_PROJECT?.toString() as string | undefined,
+ GOOGLE_TAG: import.meta.env?.VITE_GTM_PROJECT?.toString() as string | undefined
};
export const ENV = {
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index fcc41255ea..37c4267e67 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -60,11 +60,20 @@
* Handle initial load.
*/
if (!$page.url.pathname.startsWith('/auth')) {
- const acceptedRoutes = ['/login', '/register', '/recover', '/invite'];
+ const acceptedRoutes = [
+ '/login',
+ '/register',
+ '/recover',
+ '/invite',
+ '/card',
+ '/hackathon'
+ ];
if ($user) {
if (
!$page.url.pathname.startsWith('/console') &&
- !$page.url.pathname.startsWith('/invite')
+ !$page.url.pathname.startsWith('/invite') &&
+ !$page.url.pathname.startsWith('/card') &&
+ !$page.url.pathname.startsWith('/hackathon')
) {
await goto(`${base}/console`, {
replaceState: true
@@ -142,4 +151,37 @@
border-right-color: hsl(var(--p-tooltip--bg-color));
}
}
+
+ .theme-dark .with-separators {
+ --separator-color: hsl(var(--color-neutral-200));
+ --separator-text: hsl(var(--color-neutral-100));
+ }
+
+ .with-separators {
+ --separator-color: hsl(var(--color-neutral-5));
+ --separator-text: hsl(var(--color-neutral-50));
+ }
+
+ .with-separators {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+
+ text-transform: uppercase;
+ width: 100%;
+
+ color: var(--separator-text);
+
+ &::before,
+ &::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: var(--separator-color);
+ }
+ }
+
+ [type='checkbox']:where(:checked)::before {
+ content: '\ea38';
+ }
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
index 9d628c7ead..72d08d69e3 100644
--- a/src/routes/+layout.ts
+++ b/src/routes/+layout.ts
@@ -31,7 +31,9 @@ export const load: LayoutLoad = async ({ depends, url }) => {
'/invite',
'/auth/magic-url',
'/auth/oauth2/success',
- '/auth/oauth2/failure'
+ '/auth/oauth2/failure',
+ '/card',
+ '/hackathon'
];
if (!acceptedRoutes.some((n) => url.pathname.startsWith(n))) {
diff --git a/src/routes/card/+layout.svelte b/src/routes/card/+layout.svelte
new file mode 100644
index 0000000000..9a0263a423
--- /dev/null
+++ b/src/routes/card/+layout.svelte
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/card/+page.ts b/src/routes/card/+page.ts
new file mode 100644
index 0000000000..209eeb5aa0
--- /dev/null
+++ b/src/routes/card/+page.ts
@@ -0,0 +1,10 @@
+import { isCloud } from '$lib/system';
+import { redirect } from '@sveltejs/kit';
+
+export async function load({ parent }) {
+ if (!isCloud) throw redirect(303, '/');
+ const { account } = await parent();
+ if (!account) throw redirect(303, '/login');
+
+ throw redirect(303, `/card/${account.$id}`);
+}
diff --git a/src/routes/card/Card.svelte b/src/routes/card/Card.svelte
new file mode 100644
index 0000000000..d89854f824
--- /dev/null
+++ b/src/routes/card/Card.svelte
@@ -0,0 +1,458 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/card/[uid]/+page.svelte b/src/routes/card/[uid]/+page.svelte
new file mode 100644
index 0000000000..dc6332a5c9
--- /dev/null
+++ b/src/routes/card/[uid]/+page.svelte
@@ -0,0 +1,430 @@
+
+
+
+
+ {seo.title}
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+ {#if variant === 'owner'}
+
Share your card
+ {:else if variant === 'external'}
+
Share card
+ {/if}
+ {#if variant === 'external'}
+
Claim your card
+ {/if}
+
+
+

+
+
+
+
+ {#if !cardActive}
+
+
+
+ {/if}
+ {#if browser}
+
+ {/if}
+
+ {#if cardActive}
+
(cardActive = false)}
+ on:keydown={() => {
+ /* no-op */
+ }}
+ transition:fade|local />
+ {/if}
+
+
+
+
+
+
+ Get Embed Code
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/card/[uid]/+page.ts b/src/routes/card/[uid]/+page.ts
new file mode 100644
index 0000000000..5ed45e219f
--- /dev/null
+++ b/src/routes/card/[uid]/+page.ts
@@ -0,0 +1,53 @@
+import { VARS } from '$lib/system.js';
+import { redirect } from '@sveltejs/kit';
+
+function getCardImgUrls(userId: string, endpoint: string) {
+ const resolved = endpoint;
+
+ const frontImg = `${resolved}/cards/cloud?userId=${userId}`;
+ const backImg = `${resolved}/cards/cloud-back?userId=${userId}`;
+ const ogImg = `${resolved}/cards/cloud-og?userId=${userId}`;
+
+ return { frontImg, backImg, ogImg };
+}
+
+async function urlContentToDataUri(url: string): Promise
{
+ const res = await fetch(url);
+ const blob = await res.blob();
+
+ return await new Promise((callback) => {
+ const reader = new FileReader();
+ reader.onload = function () {
+ if (typeof this.result !== 'string') return '';
+ callback(this.result);
+ };
+ reader.readAsDataURL(blob);
+ });
+}
+
+export async function load({ params, url, parent }) {
+ const { account } = await parent();
+
+ const userId = params.uid;
+ const endpoint = VARS.APPWRITE_ENDPOINT ?? `${url.origin}/v1`;
+ const { frontImg, backImg } = getCardImgUrls(userId, endpoint);
+
+ const res = await fetch(frontImg);
+
+ if (!res.ok) {
+ throw redirect(303, '/');
+ }
+
+ return {
+ userId: params.uid,
+ base64: {
+ front: await urlContentToDataUri(frontImg),
+ back: await urlContentToDataUri(backImg)
+ },
+ isOwner: account && account.$id === userId,
+ imgUrls: {
+ frontImg,
+ backImg
+ }
+ };
+}
diff --git a/src/routes/console/+layout.svelte b/src/routes/console/+layout.svelte
index 870794b406..ba9f9d1c55 100644
--- a/src/routes/console/+layout.svelte
+++ b/src/routes/console/+layout.svelte
@@ -14,10 +14,20 @@
import { onMount } from 'svelte';
import { loading } from '../store';
import Create from './createOrganization.svelte';
+ export let data;
onMount(() => {
loading.set(false);
+ // Check if user already viewed cloud hackathon page
+ // if (isCloud) {
+ // const viewed = localStorage.getItem('cloud-hackathon-viewed');
+ // if (viewed !== data.account.$id) {
+ // localStorage.setItem('cloud-hackathon-viewed', data.account.$id);
+ // goto('/hackathon');
+ // }
+ // }
+
setInterval(() => {
checkForFeedback(INTERVAL);
}, INTERVAL);
@@ -50,6 +60,7 @@
showSideNavigation={$page.url.pathname !== '/console' &&
!$page?.params.organization &&
!$page.url.pathname.includes('/console/account') &&
+ !$page.url.pathname.includes('/console/card') &&
!$page.url.pathname.includes('/console/onboarding')}>
diff --git a/src/routes/console/account/organizations/[[page]]/+page.ts b/src/routes/console/account/organizations/[[page]]/+page.ts
index e51c4b1467..f0f5c57cf7 100644
--- a/src/routes/console/account/organizations/[[page]]/+page.ts
+++ b/src/routes/console/account/organizations/[[page]]/+page.ts
@@ -12,8 +12,7 @@ export const load: PageLoad = async ({ params }) => {
offset,
organizations: await sdkForConsole.teams.list([
Query.offset(offset),
- Query.limit(CARD_LIMIT),
- Query.orderDesc('$createdAt')
+ Query.limit(CARD_LIMIT)
])
};
};
diff --git a/src/routes/console/organization-[organization]/[[page]]/+page.ts b/src/routes/console/organization-[organization]/[[page]]/+page.ts
index e6f6520c38..b302f4fb16 100644
--- a/src/routes/console/organization-[organization]/[[page]]/+page.ts
+++ b/src/routes/console/organization-[organization]/[[page]]/+page.ts
@@ -13,8 +13,7 @@ export const load: PageLoad = async ({ params }) => {
projects: await sdkForConsole.projects.list([
Query.offset(offset),
Query.limit(CARD_LIMIT),
- Query.equal('teamId', params.organization),
- Query.orderDesc('$createdAt')
+ Query.equal('teamId', params.organization)
])
};
};
diff --git a/src/routes/console/project-[project]/auth/[[page]]/+page.ts b/src/routes/console/project-[project]/auth/[[page]]/+page.ts
index 132a73b2ee..7774ad5207 100644
--- a/src/routes/console/project-[project]/auth/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/auth/[[page]]/+page.ts
@@ -15,7 +15,7 @@ export const load: PageLoad = async ({ params, parent, url }) => {
search,
page,
users: await sdkForProject.users.list(
- [Query.limit(PAGE_LIMIT), Query.offset(offset), Query.orderDesc('$createdAt')],
+ [Query.limit(PAGE_LIMIT), Query.offset(offset)],
search
)
};
diff --git a/src/routes/console/project-[project]/auth/teams/[[page]]/+page.ts b/src/routes/console/project-[project]/auth/teams/[[page]]/+page.ts
index dfd5d40df2..f687ec0f75 100644
--- a/src/routes/console/project-[project]/auth/teams/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/auth/teams/[[page]]/+page.ts
@@ -15,7 +15,7 @@ export const load: PageLoad = async ({ params, parent, url }) => {
search,
page,
teams: await sdkForProject.teams.list(
- [Query.limit(PAGE_LIMIT), Query.offset(offset), Query.orderDesc('$createdAt')],
+ [Query.limit(PAGE_LIMIT), Query.offset(offset)],
search
)
};
diff --git a/src/routes/console/project-[project]/auth/teams/team-[team]/members/[[page]]/+page.ts b/src/routes/console/project-[project]/auth/teams/team-[team]/members/[[page]]/+page.ts
index 38c6fd9300..646165c70c 100644
--- a/src/routes/console/project-[project]/auth/teams/team-[team]/members/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/auth/teams/team-[team]/members/[[page]]/+page.ts
@@ -17,7 +17,7 @@ export const load: PageLoad = async ({ params, parent, depends, url }) => {
search,
memberships: await sdkForProject.teams.listMemberships(
teamId,
- [Query.limit(PAGE_LIMIT), Query.offset(offset), Query.orderDesc('$createdAt')],
+ [Query.limit(PAGE_LIMIT), Query.offset(offset)],
search
)
};
diff --git a/src/routes/console/project-[project]/databases/[[page]]/+page.ts b/src/routes/console/project-[project]/databases/[[page]]/+page.ts
index 47cc014c6a..f854f6f191 100644
--- a/src/routes/console/project-[project]/databases/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/databases/[[page]]/+page.ts
@@ -13,8 +13,7 @@ export const load: PageLoad = async ({ params, parent }) => {
offset,
databases: await sdkForProject.databases.list([
Query.limit(CARD_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/databases/database-[database]/[[page]]/+page.ts b/src/routes/console/project-[project]/databases/database-[database]/[[page]]/+page.ts
index d7c69f3caf..eba0b24b9e 100644
--- a/src/routes/console/project-[project]/databases/database-[database]/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/databases/database-[database]/[[page]]/+page.ts
@@ -13,8 +13,7 @@ export const load: PageLoad = async ({ params, parent }) => {
offset,
collections: await sdkForProject.databases.listCollections(params.database, [
Query.limit(CARD_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/[[page]]/+page.ts b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/[[page]]/+page.ts
index 7c19bb9dca..56ff066f34 100644
--- a/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/databases/database-[database]/collection-[collection]/[[page]]/+page.ts
@@ -14,8 +14,7 @@ export const load: PageLoad = async ({ params, parent, depends }) => {
offset,
documents: await sdkForProject.databases.listDocuments(params.database, params.collection, [
Query.limit(PAGE_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/functions/[[page]]/+page.ts b/src/routes/console/project-[project]/functions/[[page]]/+page.ts
index 3c3b826a6a..19f53a6b06 100644
--- a/src/routes/console/project-[project]/functions/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/functions/[[page]]/+page.ts
@@ -14,8 +14,7 @@ export const load: PageLoad = async ({ params, parent, depends }) => {
offset,
functions: await sdkForProject.functions.list([
Query.limit(CARD_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte
index af41f1d464..7d05f312ef 100644
--- a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte
+++ b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte
@@ -29,17 +29,18 @@
import { log } from '$lib/stores/logs';
import { invalidate } from '$app/navigation';
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
- import type { Models } from '@aw-labs/appwrite-console';
+ import { Query, type Models } from '@aw-labs/appwrite-console';
import type { PageData } from './$types';
import Delete from '../delete.svelte';
import Create from '../create.svelte';
import Activate from '../activate.svelte';
import { browser } from '$app/environment';
- import { sdkForConsole } from '$lib/stores/sdk';
+ import { sdkForConsole, sdkForProject } from '$lib/stores/sdk';
import { page } from '$app/stores';
import Output from '$lib/components/output.svelte';
import { calculateTime } from '$lib/helpers/timeConversion';
import { timer } from '$lib/actions/timer';
+ import { onMount } from 'svelte';
export let data: PageData;
@@ -49,13 +50,23 @@
let showActivate = false;
let selectedDeployment: Models.Deployment = null;
+ let activeDeployment: Models.Deployment = null;
+
+ onMount(async () => {
+ activeDeployment = await getActiveDeployment();
+ });
+
+ async function getActiveDeployment() {
+ const list = await sdkForProject.functions.listDeployments($page.params.function, [
+ Query.equal('$id', $func?.deployment)
+ ]);
+ return list?.deployments?.[0];
+ }
const handleActivate = () => {
invalidate(Dependencies.DEPLOYMENTS);
};
- $: activeDeployment = data.deployments.deployments.find((d) => d.$id === $func?.deployment);
-
if (browser) {
sdkForConsole.client.subscribe('console', (message) => {
if (message.events.includes('functions.*.deployments.*.create')) {
diff --git a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.ts
index 9472fd6af1..3160a72605 100644
--- a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.ts
@@ -14,8 +14,7 @@ export const load: PageLoad = async ({ params, parent, depends }) => {
offset,
deployments: await sdkForProject.functions.listDeployments(params.function, [
Query.limit(PAGE_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.ts
index 5d5c50f056..5a1b64c054 100644
--- a/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.ts
@@ -14,8 +14,7 @@ export const load: PageLoad = async ({ params, parent, depends }) => {
offset,
executions: await sdkForProject.functions.listExecutions(params.function, [
Query.limit(PAGE_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/overview/requests.svelte b/src/routes/console/project-[project]/overview/requests.svelte
index 30e6509863..762861054a 100644
--- a/src/routes/console/project-[project]/overview/requests.svelte
+++ b/src/routes/console/project-[project]/overview/requests.svelte
@@ -54,7 +54,7 @@
series={[
{
name: 'Requests',
- data: [...requests.map((e) => [e.date, e.value])]
+ data: [...(requests?.map((e) => [e.date, e.value]) ?? [])]
}
]} />
diff --git a/src/routes/console/project-[project]/storage/[[page]]/+page.ts b/src/routes/console/project-[project]/storage/[[page]]/+page.ts
index 30ed7b167c..8384dd85eb 100644
--- a/src/routes/console/project-[project]/storage/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/storage/[[page]]/+page.ts
@@ -13,8 +13,7 @@ export const load: PageLoad = async ({ params, parent }) => {
offset,
buckets: await sdkForProject.storage.listBuckets([
Query.limit(CARD_LIMIT),
- Query.offset(offset),
- Query.orderDesc('$createdAt')
+ Query.offset(offset)
])
};
};
diff --git a/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.ts b/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.ts
index 0c15a026ef..23abe1ae59 100644
--- a/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.ts
+++ b/src/routes/console/project-[project]/storage/bucket-[bucket]/[[page]]/+page.ts
@@ -16,7 +16,7 @@ export const load: PageLoad = async ({ params, parent, depends, url }) => {
search,
files: await sdkForProject.storage.listFiles(
params.bucket,
- [Query.limit(PAGE_LIMIT), Query.offset(offset), Query.orderDesc('$createdAt')],
+ [Query.limit(PAGE_LIMIT), Query.offset(offset)],
search
)
};
diff --git a/src/routes/hackathon/+layout.svelte b/src/routes/hackathon/+layout.svelte
new file mode 100644
index 0000000000..9a0263a423
--- /dev/null
+++ b/src/routes/hackathon/+layout.svelte
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/hackathon/+page.svelte b/src/routes/hackathon/+page.svelte
new file mode 100644
index 0000000000..e7b73713c2
--- /dev/null
+++ b/src/routes/hackathon/+page.svelte
@@ -0,0 +1,260 @@
+
+
+
+
+ Appwrite Cloud - Join Our Hackathon
+
+
+
+
+
+ Join Our
+
+ Cloud Hackathon
+
+
+ -
+ Build an open-source app using Appwrite Cloud
+
+ -
+ Publish an article on your Hashnode blog
+
+ -
+
+ Submit your project on Built with Appwrite
+
+
+
+
+
+
+
+
+
+
+ -
+
+

+
+
+

+
+
+ -
+
+

+
+
+

+
+
+
+
+
+
+
+

+
+
+
+ Grand winner
+
+
+ 5,000USD
+
+
+
+
+ Appwrite swag
+
+ Hashnode T-shirt & mug
+
+
+
+
+ 5 Runner-ups Each
+
+
+ 1,000USD
+
+
+
+ Appwrite swag
+
+ Hashnode T-shirt
+
+
+
+
+
+
diff --git a/src/routes/hackathon/+page.ts b/src/routes/hackathon/+page.ts
new file mode 100644
index 0000000000..bbeeb2f696
--- /dev/null
+++ b/src/routes/hackathon/+page.ts
@@ -0,0 +1,8 @@
+import { isCloud } from '$lib/system';
+import { redirect } from '@sveltejs/kit';
+
+export async function load({ parent }) {
+ if (!isCloud) throw redirect(303, '/');
+ const { account } = await parent();
+ if (!account) throw redirect(303, '/login');
+}
diff --git a/src/routes/hackathon/cloud-dark.svg b/src/routes/hackathon/cloud-dark.svg
new file mode 100644
index 0000000000..e90b2fa6b8
--- /dev/null
+++ b/src/routes/hackathon/cloud-dark.svg
@@ -0,0 +1,22 @@
+
diff --git a/src/routes/hackathon/cloud-light.svg b/src/routes/hackathon/cloud-light.svg
new file mode 100644
index 0000000000..901a6eafdb
--- /dev/null
+++ b/src/routes/hackathon/cloud-light.svg
@@ -0,0 +1,22 @@
+
diff --git a/src/routes/hackathon/hackathon-badge.svg b/src/routes/hackathon/hackathon-badge.svg
new file mode 100644
index 0000000000..adfbc82f1b
--- /dev/null
+++ b/src/routes/hackathon/hackathon-badge.svg
@@ -0,0 +1,154 @@
+
diff --git a/src/routes/hackathon/hashnode-dark.svg b/src/routes/hackathon/hashnode-dark.svg
new file mode 100644
index 0000000000..0fa043ce23
--- /dev/null
+++ b/src/routes/hackathon/hashnode-dark.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/routes/hackathon/hashnode-light.svg b/src/routes/hackathon/hashnode-light.svg
new file mode 100644
index 0000000000..e85da8ba45
--- /dev/null
+++ b/src/routes/hackathon/hashnode-light.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte
index b2f488a901..0b563cdfd4 100644
--- a/src/routes/login/+page.svelte
+++ b/src/routes/login/+page.svelte
@@ -37,6 +37,15 @@
trackError(error, Submit.AccountCreate);
}
}
+
+ function onGithubLogin() {
+ sdkForConsole.account.createOAuth2Session(
+ 'github',
+ window.location.origin,
+ window.location.origin,
+ ['read:user', 'user:email']
+ );
+ }
@@ -66,6 +75,13 @@
+ or
+
+
+
diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte
index 03657a94b6..61f11b7555 100644
--- a/src/routes/register/+page.svelte
+++ b/src/routes/register/+page.svelte
@@ -15,7 +15,7 @@
import { Unauthenticated } from '$lib/layout';
import FormList from '$lib/elements/forms/formList.svelte';
import { Dependencies } from '$lib/constants';
- import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
+ import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { ID } from '@aw-labs/appwrite-console';
let name: string, mail: string, pass: string, disabled: boolean;
@@ -38,6 +38,15 @@
trackError(error, Submit.AccountCreate);
}
}
+
+ function onGithubLogin() {
+ sdkForConsole.account.createOAuth2Session(
+ 'github',
+ window.location.origin,
+ window.location.origin,
+ ['read:user', 'user:email']
+ );
+ }
@@ -53,20 +62,21 @@
id="name"
label="Name"
placeholder="Your name"
- autofocus={true}
+ autofocus
+ required
bind:value={name} />
By registering, you agree that you have read, understand, and acknowledge our
+ or
+
+
+
diff --git a/static/images/cloud-beta-hoodies.png b/static/images/cloud-beta-hoodies.png
new file mode 100644
index 0000000000..a076484074
Binary files /dev/null and b/static/images/cloud-beta-hoodies.png differ
diff --git a/static/images/hoodie-1.png b/static/images/hoodie-1.png
new file mode 100644
index 0000000000..6d2547e37e
Binary files /dev/null and b/static/images/hoodie-1.png differ
diff --git a/static/images/hoodie-2.png b/static/images/hoodie-2.png
new file mode 100644
index 0000000000..5735f48bc9
Binary files /dev/null and b/static/images/hoodie-2.png differ
diff --git a/static/images/hoodies-bg.png b/static/images/hoodies-bg.png
new file mode 100644
index 0000000000..37a8803534
Binary files /dev/null and b/static/images/hoodies-bg.png differ