Feat: Depreciate Webflow API call for tutorials (#3911)

This commit is contained in:
Mike
2025-01-29 14:48:50 +01:00
committed by GitHub
parent 3c7b6e2626
commit 1b6569dbac
9 changed files with 100 additions and 155 deletions
+1 -3
View File
@@ -41,6 +41,4 @@ NUXT_PUBLIC_SURVICATE_WORKSPACE_KEY=
NUXT_PUBLIC_ENABLE_DIRECT_PREVIEWS=true
# Ghost API
NUXT_PUBLIC_GHOST_API_KEY=
NUXT_WEBFLOW_API_TOKEN=8c9bea4c120742a21ff308cda0bea73f13e89ffe26dcc886990bba353549b652
NUXT_PUBLIC_GHOST_API_KEY=
@@ -1,25 +1,18 @@
<template>
<NuxtLink :to="webflowItem.url" target="_blank" @click="trackClick">
<NuxtLink :to="tutorialItem.url" target="_blank" @click="trackClick">
<div
class="bg-foundation border border-outline-3 rounded-xl flex flex-col overflow-hidden hover:border-outline-5 transition"
>
<NuxtImg
v-if="webflowItem.featureImageUrl"
:src="webflowItem.featureImageUrl"
:alt="webflowItem.title"
:src="tutorialItem.image"
:alt="tutorialItem.title"
class="h-32 w-full object-cover"
width="400"
height="225"
/>
<div
v-else
class="bg-foundation-page w-full h-32 flex items-center justify-center"
>
<HeaderLogoBlock no-link minimal class="scale-150" />
</div>
<div class="p-5">
<h3 class="text-body-2xs text-foreground truncate">
{{ webflowItem.title }}
{{ tutorialItem.title }}
</h3>
</div>
</div>
@@ -27,19 +20,19 @@
</template>
<script lang="ts" setup>
import type { WebflowItem } from '~/lib/dashboard/helpers/types'
import type { TutorialItem } from '~/lib/dashboard/helpers/types'
import { useMixpanel } from '~~/lib/core/composables/mp'
const mixpanel = useMixpanel()
const props = defineProps<{
webflowItem: WebflowItem
tutorialItem: TutorialItem
}>()
const trackClick = () => {
mixpanel.track('Tutorial clicked', {
title: props.webflowItem.title,
id: props.webflowItem.id
title: props.tutorialItem.title,
url: props.tutorialItem.url
})
}
</script>
@@ -1,31 +0,0 @@
<template>
<section v-if="!error">
<h2 class="text-heading-sm text-foreground-2 mb-4">Tutorials</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<DashboardTutorialsCard
v-for="webflowItem in webflowItems"
:key="webflowItem.id"
:webflow-item="webflowItem"
/>
</div>
</section>
<section v-else />
</template>
<script setup lang="ts">
import type { WebflowItem } from '~/lib/dashboard/helpers/types'
const logger = useLogger()
const { data: webflowData, error } = await useAsyncData<{
items: WebflowItem[]
}>('webflow-items', () =>
$fetch<{ items: WebflowItem[] }>('/api/webflow', {
onResponseError({ response }) {
logger.error('API Response Error:', response.status, response.statusText)
}
})
)
const webflowItems = computed(() => webflowData.value?.items || [])
</script>
@@ -4171,7 +4171,7 @@ export type WebhookUpdateInput = {
export type Workspace = {
__typename?: 'Workspace';
/** Get all join requests for all the workspaces the user is an admin of */
adminWorkspacesJoinRequests: WorkspaceJoinRequestCollection;
adminWorkspacesJoinRequests?: Maybe<WorkspaceJoinRequestCollection>;
automateFunctions: AutomateFunctionCollection;
createdAt: Scalars['DateTime']['output'];
/** Info about the workspace creation state */
@@ -4975,7 +4975,7 @@ export type SettingsWorkspacesMembersInvitesTable_PendingWorkspaceCollaboratorFr
export type SettingsWorkspacesMembersInvitesTable_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, domainBasedMembershipProtectionEnabled: boolean, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, inviteId: string, role: string, title: string, updatedAt: string, user?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> | null, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null };
export type SettingsWorkspacesMembersRequestsTable_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, domainBasedMembershipProtectionEnabled: boolean, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> }, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null };
export type SettingsWorkspacesMembersRequestsTable_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, domainBasedMembershipProtectionEnabled: boolean, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null };
export type SettingsWorkspacesMembersMembersTable_WorkspaceCollaboratorFragment = { __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string, company?: string | null, verified?: boolean | null, workspaceDomainPolicyCompliant?: boolean | null } };
@@ -5003,11 +5003,11 @@ export type MoveProjectsDialog_WorkspaceFragment = { __typename?: 'Workspace', i
export type MoveProjectsDialog_UserFragment = { __typename?: 'User', projects: { __typename?: 'UserProjectCollection', items: Array<{ __typename?: 'Project', role?: string | null, id: string, name: string, workspace?: { __typename?: 'Workspace', id: string } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number } }> } };
export type WorkspaceProjectList_WorkspaceFragment = { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceProjectList_WorkspaceFragment = { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceProjectList_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> };
export type WorkspaceHeader_WorkspaceFragment = { __typename?: 'Workspace', slug: string, readOnly: boolean, id: string, name: string, role?: string | null, description?: string | null, logo?: string | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceHeader_WorkspaceFragment = { __typename?: 'Workspace', slug: string, readOnly: boolean, id: string, name: string, role?: string | null, description?: string | null, logo?: string | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceInviteBanner_PendingWorkspaceCollaboratorFragment = { __typename?: 'PendingWorkspaceCollaborator', id: string, workspaceId: string, workspaceName: string, token?: string | null, workspaceSlug: string, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string } | null };
@@ -5019,11 +5019,11 @@ export type WorkspaceJoinRequestApproveDialog_WorkspaceJoinRequestFragment = { _
export type WorkspaceSidebarAbout_WorkspaceFragment = { __typename?: 'Workspace', id: string, name: string, description?: string | null };
export type WorkspaceSidebarMembers_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceSidebarMembers_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceSidebarSecurity_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null };
export type WorkspaceSidebar_WorkspaceFragment = { __typename?: 'Workspace', slug: string, id: string, name: string, description?: string | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceSidebar_WorkspaceFragment = { __typename?: 'Workspace', slug: string, id: string, name: string, description?: string | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceWizard_WorkspaceFragment = { __typename?: 'Workspace', name: string, slug: string, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null };
@@ -6054,7 +6054,7 @@ export type SettingsWorkspacesMembersQueryVariables = Exact<{
}>;
export type SettingsWorkspacesMembersQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, role?: string | null, name: string, domainBasedMembershipProtectionEnabled: boolean, team: { __typename?: 'WorkspaceCollaboratorCollection', items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string, company?: string | null, verified?: boolean | null, workspaceDomainPolicyCompliant?: boolean | null }, projectRoles: Array<{ __typename?: 'ProjectRole', role: string, project: { __typename?: 'Project', id: string, name: string } }> }> }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, inviteId: string, role: string, title: string, updatedAt: string, user?: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> | null, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> }, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null } };
export type SettingsWorkspacesMembersQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, role?: string | null, name: string, domainBasedMembershipProtectionEnabled: boolean, team: { __typename?: 'WorkspaceCollaboratorCollection', items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string, company?: string | null, verified?: boolean | null, workspaceDomainPolicyCompliant?: boolean | null }, projectRoles: Array<{ __typename?: 'ProjectRole', role: string, project: { __typename?: 'Project', id: string, name: string } }> }> }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, inviteId: string, role: string, title: string, updatedAt: string, user?: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> | null, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null } };
export type SettingsWorkspacesMembersSearchQueryVariables = Exact<{
slug: Scalars['String']['input'];
@@ -6070,7 +6070,7 @@ export type SettingsWorkspacesJoinRequestsSearchQueryVariables = Exact<{
}>;
export type SettingsWorkspacesJoinRequestsSearchQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, role?: string | null, domainBasedMembershipProtectionEnabled: boolean, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> }, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null } };
export type SettingsWorkspacesJoinRequestsSearchQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, role?: string | null, domainBasedMembershipProtectionEnabled: boolean, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, createdAt: string, status: WorkspaceJoinRequestStatus, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string }, workspace: { __typename?: 'Workspace', id: string } }> } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null, subscription?: { __typename?: 'WorkspaceSubscription', seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null } };
export type SettingsWorkspacesInvitesSearchQueryVariables = Exact<{
slug: Scalars['String']['input'];
@@ -6275,7 +6275,7 @@ export type WorkspaceDashboardAbout_WorkspaceFragment = { __typename?: 'Workspac
export type WorkspaceInvitedTeam_WorkspaceFragment = { __typename?: 'Workspace', id: string, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceTeam_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceTeam_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null };
export type WorkspaceSecurity_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null };
@@ -6372,7 +6372,7 @@ export type WorkspacePageQueryQueryVariables = Exact<{
}>;
export type WorkspacePageQueryQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null }, workspaceInvite?: { __typename?: 'PendingWorkspaceCollaborator', id: string, workspaceId: string, workspaceName: string, token?: string | null, title: string, email?: string | null, workspaceSlug: string, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } | null } | null };
export type WorkspacePageQueryQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null }, workspaceInvite?: { __typename?: 'PendingWorkspaceCollaborator', id: string, workspaceId: string, workspaceName: string, token?: string | null, title: string, email?: string | null, workspaceSlug: string, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } | null } | null };
export type WorkspaceProjectsQueryQueryVariables = Exact<{
workspaceSlug: Scalars['String']['input'];
@@ -6444,7 +6444,7 @@ export type OnWorkspaceUpdatedSubscriptionVariables = Exact<{
}>;
export type OnWorkspaceUpdatedSubscription = { __typename?: 'Subscription', workspaceUpdated: { __typename?: 'WorkspaceUpdatedMessage', id: string, workspace: { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number }, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null } } };
export type OnWorkspaceUpdatedSubscription = { __typename?: 'Subscription', workspaceUpdated: { __typename?: 'WorkspaceUpdatedMessage', id: string, workspace: { __typename?: 'Workspace', id: string, readOnly: boolean, name: string, slug: string, role?: string | null, description?: string | null, logo?: string | null, domainBasedMembershipProtectionEnabled: boolean, discoverabilityEnabled: boolean, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }> }, creationState?: { __typename?: 'WorkspaceCreationState', completed: boolean, state: {} } | null, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, createdAt: string, name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', id: string, avatar?: string | null, name: string } }> }, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', id: string, domain: string }> | null, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string, seats: { __typename?: 'WorkspaceSubscriptionSeats', guest: number, plan: number } } | null, defaultRegion?: { __typename?: 'ServerRegionItem', key: string, id: string, name: string } | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null } } };
export type LegacyBranchRedirectMetadataQueryVariables = Exact<{
streamId: Scalars['String']['input'];
@@ -6524,7 +6524,7 @@ export type SettingsWorkspacesBilling_WorkspaceFragment = { __typename?: 'Worksp
export type SettingsWorkspacesGeneral_WorkspaceFragment = { __typename?: 'Workspace', id: string, name: string, slug: string, description?: string | null, logo?: string | null, role?: string | null, defaultProjectRole: string, plan?: { __typename?: 'WorkspacePlan', status: WorkspacePlanStatuses, name: WorkspacePlans } | null };
export type SettingsWorkspacesMembers_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, team: { __typename?: 'WorkspaceCollaboratorCollection', items: Array<{ __typename?: 'WorkspaceCollaborator', id: string }> }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', user?: { __typename?: 'LimitedUser', id: string } | null }> | null, adminWorkspacesJoinRequests: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } };
export type SettingsWorkspacesMembers_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, team: { __typename?: 'WorkspaceCollaboratorCollection', items: Array<{ __typename?: 'WorkspaceCollaborator', id: string }> }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', user?: { __typename?: 'LimitedUser', id: string } | null }> | null, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number } | null };
export type SettingsWorkspacesProjects_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> };
@@ -0,0 +1,52 @@
import type { TutorialItem } from '~/lib/dashboard/helpers/types'
export const tutorials: TutorialItem[] = [
{
title: 'How To Get Data From Grasshopper Into Power BI',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/677d34c3f1e3b99aa578bfea_GH%20to%20PBI%20tutorial-p-800.jpg',
url: 'https://www.speckle.systems/tutorials/best-way-to-get-data-from-grasshopper-into-power-bi'
},
{
title: 'Automating CFD Analysis with Speckle',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c508e14c68996f7aa1f5_66d648086cd656dae5168a85_Tutorial-Graphics-automate-centeres-cfd-1.png',
url: 'https://www.speckle.systems/tutorials/automating-cfd-analysis-with-speckle'
},
{
title: 'PowerQuery(QL) for AEC Data Analysis',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c49549279bcda21c3115_66e047f5c915694aefb78105_powerquery-specklecon%25400.5x.png',
url: 'https://www.speckle.systems/tutorials/powerquery-ql-for-aec-data-analysis'
},
{
title: 'From Grasshopper Placeholders to Unreal Assets',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c50919d477e7b4454747_66e047f5b7f992018acdb66b_grasshopper-unreal%25400.5x.png',
url: 'https://www.speckle.systems/tutorials/from-grasshopper-placeholders-to-unreal-assets'
},
{
title: 'Rhino Block to Revit Family',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c50a49279bcda21c9483_66e047f58da87f021da53e06_rhino-2-rvt-families%25400.5x.png',
url: 'https://www.speckle.systems/tutorials/rhino-block-to-revit-family'
},
{
title: 'SketchUp Components to Revit Families',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c50ac6269f3166039982_66e047f51d1cb84078e7320a_skp-2-rvt-families%25400.5x.png',
url: 'https://www.speckle.systems/tutorials/sketchup-components-to-revit-families'
},
{
title: 'Block to Family Conversion with Speckle',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c50ac50a28b58fe0e10b_66e047f505114bd4a6854b6a_216-blocks-to-families%25400.5x.png',
url: 'https://www.speckle.systems/tutorials/new-in-2-16-block-to-family-conversion'
},
{
title: 'SketchUp Connector for Mac',
image:
'https://cdn.prod.website-files.com/66c31b5a50432200dc753cc4/66f9c508c50a28b58fe0ddef_66e047f6aacfa88a6524a956_final-blog.jpeg',
url: 'https://www.speckle.systems/tutorials/sketchup-connector-for-mac'
}
]
@@ -1,11 +1,8 @@
import { type LayoutDialogButton } from '@speckle/ui-components'
export type WebflowItem = {
id: string
export type TutorialItem = {
title: string
createdOn: string
lastPublished: string
featureImageUrl?: string
image: string
url: string
}
-1
View File
@@ -48,7 +48,6 @@ export default defineNuxtConfig({
],
runtimeConfig: {
redisUrl: '',
webflowApiToken: '',
public: {
...featureFlags,
apiOrigin: 'UNDEFINED',
+25 -2
View File
@@ -53,7 +53,29 @@
</div>
</section>
</div>
<DashboardTutorialsWrapper />
<section>
<div class="flex items-center justify-between">
<h2 class="text-heading-sm text-foreground-2">Tutorials</h2>
<FormButton
color="outline"
size="sm"
to="https://www.speckle.systems/tutorials"
external
target="_blank"
>
View all
</FormButton>
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 pt-5"
>
<DashboardTutorialCard
v-for="tutorialItem in tutorialItems"
:key="tutorialItem.title"
:tutorial-item="tutorialItem"
/>
</div>
</section>
</div>
<ProjectsAddDialog v-model:open="openNewProject" />
@@ -78,6 +100,7 @@ import { downloadManager } from '~~/lib/common/utils/downloadManager'
import { ToastNotificationType, useGlobalToast } from '~~/lib/common/composables/toast'
import type { LayoutDialogButton } from '@speckle/ui-components'
import type { PromoBanner } from '~/lib/promo-banners/types'
import { tutorials } from '~/lib/dashboard/helpers/tutorials'
useHead({ title: 'Dashboard' })
@@ -101,7 +124,7 @@ const { isGuest } = useActiveUser()
const router = useRouter()
const openNewProject = ref(false)
const tutorialItems = shallowRef(tutorials)
const quickStartItems = shallowRef<QuickStartItem[]>([
{
title: 'Install Speckle manager',
-86
View File
@@ -1,86 +0,0 @@
import { ensureError } from '@speckle/shared'
import type { WebflowItem } from '~/lib/dashboard/helpers/types'
type WebflowApiResponse = {
items: Array<{
id: string
lastPublished: string
createdOn: string
fieldData: {
name: string
slug: string
'feature-image'?: {
url: string
}
html?: string
}
}>
}
// Used to filter to last 6 months' articles to prevent old,
// recently edited posts from appearing at the top
const getSixMonthsAgo = (): Date => {
const date = new Date()
date.setMonth(date.getMonth() - 6)
return date
}
export default defineEventHandler(async (): Promise<{ items: WebflowItem[] }> => {
const { webflowApiToken } = useRuntimeConfig()
const logger = useLogger()
if (!webflowApiToken) {
logger.info('Webflow API token is not set. Returning an empty array of items.')
return { items: [] }
}
const url =
'https://api.webflow.com/v2/collections/66d79d1c9cdda972d5c718b4/items?limit=16&sortBy=lastPublished&sortOrder=desc'
try {
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${webflowApiToken}`,
'accept-version': '2.0.0'
}
})
if (!response.ok) {
const errMsg = `Webflow API Error: ${response.status} ${response.statusText}`
throw createError({
statusCode: response.status,
fatal: true,
message: errMsg
})
}
const data = (await response.json()) as WebflowApiResponse
const sixMonthsAgo = getSixMonthsAgo()
const filteredItems = data.items
.filter((item) => new Date(item.createdOn) > sixMonthsAgo)
.sort((a, b) => new Date(b.createdOn).getTime() - new Date(a.createdOn).getTime())
.slice(0, 8) // Take only the first 8 items after filtering and sorting
return {
items: filteredItems.map(
(item): WebflowItem => ({
id: item.id,
title: item.fieldData.name,
createdOn: item.createdOn,
lastPublished: item.lastPublished,
featureImageUrl: item.fieldData['feature-image']?.url,
url: `https://speckle.systems/tutorials/${item.fieldData.slug}`
})
)
}
} catch (e) {
const errMsg = ensureError(e).message
throw createError({
statusCode: 500,
fatal: true,
message: `Error fetching webflow items: ${errMsg}`
})
}
})