diff --git a/src/lib/components/bottomModalAlert.svelte b/src/lib/components/bottomModalAlert.svelte index ab9897bb97..08090a8944 100644 --- a/src/lib/components/bottomModalAlert.svelte +++ b/src/lib/components/bottomModalAlert.svelte @@ -141,11 +141,12 @@ // the button component cannot have both href and on:click! function triggerWindowLink(alert: BottomModalAlertItem, event?: string) { const alertAction = alert.cta; - const shouldShowUpgrade = canUpgrade($organization?.billingPlanDetails); + const shouldShowUpgrade = + !alertAction.skipUpgradeRedirect && canUpgrade($organization?.billingPlanDetails); // for correct event tracking after removal const currentModalId = currentModalAlert.id; - const organizationId = $project.teamId ?? $organization.$id; + const organizationId = $project?.teamId ?? $organization?.$id; const url = shouldShowUpgrade ? getChangePlanUrl(organizationId) diff --git a/src/lib/images/promos/claude-code-plugin.png b/src/lib/images/promos/claude-code-plugin.png new file mode 100644 index 0000000000..8776b9b382 Binary files /dev/null and b/src/lib/images/promos/claude-code-plugin.png differ diff --git a/src/lib/stores/bottom-alerts.ts b/src/lib/stores/bottom-alerts.ts index b0a044f1a6..33d2bf5248 100644 --- a/src/lib/stores/bottom-alerts.ts +++ b/src/lib/stores/bottom-alerts.ts @@ -11,6 +11,7 @@ export type BottomModalAlertAction = { hideOnClick?: boolean; link: (ctx: { organization: Models.Organization; project: Models.Project }) => string; external?: boolean; + skipUpgradeRedirect?: boolean; }; /** diff --git a/src/routes/(console)/bottomAlerts.ts b/src/routes/(console)/bottomAlerts.ts index 1ec0a224b1..2aa489dfba 100644 --- a/src/routes/(console)/bottomAlerts.ts +++ b/src/routes/(console)/bottomAlerts.ts @@ -1,6 +1,37 @@ +import { isCloud } from '$lib/system'; import { isSameDay } from '$lib/helpers/date'; +import { type BottomModalAlertItem, showBottomModalAlert } from '$lib/stores/bottom-alerts'; +import ClaudeCodePlugin from '$lib/images/promos/claude-code-plugin.png'; -export function addBottomModalAlerts() {} +const listOfPromotions: BottomModalAlertItem[] = []; + +if (isCloud) { + const claudePluginPromo: BottomModalAlertItem = { + id: 'modal:claude_plugin_announcement', + src: { + dark: ClaudeCodePlugin, + light: ClaudeCodePlugin + }, + title: 'Announcing the Appwrite Claude plugin', + message: 'Build, manage, and ship Appwrite projects without leaving Claude Code.', + plan: 'free', + importance: 8, + scope: 'everywhere', + cta: { + text: 'Read announcement', + link: () => 'https://appwrite.io/blog/post/announcing-appwrite-claude-code-plugin', + external: true, + hideOnClick: true, + skipUpgradeRedirect: true + }, + show: true + }; + listOfPromotions.push(claudePluginPromo); +} + +export function addBottomModalAlerts() { + listOfPromotions.forEach((promotion) => showBottomModalAlert(promotion)); +} // use this for time based promo handling // noinspection JSUnusedGlobalSymbols