Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
#	app/app.vue
#	app/composables/useNavigation.ts
#	content/3.deploy/zerops.md
#	content/5.video-courses.yml
#	nuxt.config.ts
  • Loading branch information
Ivan Bochkarev committed Oct 23, 2024
2 parents 91fd165 + 81fb676 commit 531d853
Show file tree
Hide file tree
Showing 138 changed files with 1,375 additions and 1,095 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

## Настройка

Убедитесь в том, что установили зависимости
Make sure to enable corepack and install the dependencies:

```bash
corepack enable
pnpm install
```

Expand Down
File renamed without changes.
16 changes: 11 additions & 5 deletions app.vue → app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ onMounted(() => {
<NuxtLoadingIndicator />

<AppBanner
id="nuxt-cert-date"
to="https://certificates.dev/nuxt?utm_source=nuxt&utm_medium=website&utm_campaign=affiliate&friend=NUXT"
id="nuxt-nation-2024"
to="https://nuxtnation.com/?utm_source=nuxt&utm_medium=website&utm_campaign=banner"
>
<div class="flex items-center gap-1">
<UIcon
name="i-ph-circle-wavy-check-duotone"
name="i-ph-microphone-stage-duotone"
class="w-5 h-5 flex-shrink-0 pointer-events-none hidden sm:inline-block"
/>
<span><span class="hidden lg:inline">Official</span> Nuxt mid-level certification launch date announced!</span>
<span><span class="font-semibold">Nuxt Nation</span> conference is coming. Join us on November 12-13.</span>
<UButton
label="Узнать больше"
label="Sign up"
color="white"
trailing-icon="i-ph-arrow-right"
size="2xs"
Expand Down Expand Up @@ -135,3 +135,9 @@ onMounted(() => {
</ClientOnly>
</div>
</template>
<style>
#kapa-widget-container {
visibility: hidden;
}
</style>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defineProps<{
:key="index"
v-bind="feature"
:ui="{
base: 'overflow-hidden',
background: 'dark:bg-gradient-to-b from-gray-700/50 to-gray-900/50',
body: {
base: 'flex-1',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
69 changes: 48 additions & 21 deletions composables/useNavigation.ts → app/composables/useNavigation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createSharedComposable } from '@vueuse/core'

const _useNavigation = () => {
const nuxtApp = useNuxtApp()
const headerLinks = computed(() => {
const route = useRoute()

Expand Down Expand Up @@ -178,32 +179,58 @@ const _useNavigation = () => {
}]
}]

const searchLinks = computed(() => [...headerLinks.value.map((link) => {
const searchLinks = computed(() => [
{
label: 'Ask AI',
icon: 'i-ph-magic-wand',
to: 'javascript:void(0);',
// @ts-expect-error this is not typed
click: () => nuxtApp.$kapa?.openModal()
},
...headerLinks.value.map((link) => {
// Remove `/docs` and `/enterprise` links from command palette
if (link.search === false) {
return {
label: link.label,
icon: link.icon,
children: link.children
if (link.search === false) {
return {
label: link.label,
icon: link.icon,
children: link.children
}
}
}

return link
}).filter(Boolean), {
label: 'Команда',
icon: 'i-ph-users',
to: '/team'
}, {
label: 'Набор для дизайна',
icon: 'i-ph-palette',
to: '/design-kit'
}, {
label: 'Рассылка',
icon: 'i-ph-envelope-simple',
to: '/newsletter'
}])
return link
}).filter(Boolean), {
label: 'Команда',
icon: 'i-ph-users',
to: '/team'
}, {
label: 'Набор для дизайна',
icon: 'i-ph-palette',
to: '/design-kit'
}, {
label: 'Рассылка',
icon: 'i-ph-envelope-simple',
to: '/newsletter'
}])

const searchGroups = [{
key: 'ask-ai-search',
label: 'ИИ',
icon: 'i-ph-magic-wand',
search: async (q) => {
if (!q) {
return []
}

return [{
label: `Спросите ИИ о "${q}"`,
icon: 'i-ph-magic-wand',
to: 'javascript:void(0);',
click() {
return nuxtApp.$kapa.openModal(q)
}
}]
}
}, {
key: 'modules-search',
label: 'Модули',
search: async (q) => {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
25 changes: 21 additions & 4 deletions pages/video-courses.vue → app/pages/video-courses.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,23 @@ defineOgImageComponent('Docs')
<NuxtImg
:src="`/assets/video-courses/${course.slug}.png`"
:alt="course.name"
width="58"
height="32"
:width="'sponsor' in course && course.sponsor ? 96 : 58"
:height="'sponsor' in course && course.sponsor ? 64 : 32"
format="webp"
:modifiers="{ pos: 'top' }"
:loading="index > 3 ? 'lazy' : undefined"
class="rounded border dark:border-gray-800 object-cover mr-2 hidden lg:block"
/>
<h3 class="text-base font-medium text-gray-700 dark:text-gray-200 flex-grow lg:flex-grow-0">
<h3
class="font-medium text-gray-700 dark:text-gray-200 flex-grow lg:flex-grow-0"
:class="'sponsor' in course && course.sponsor ? 'text-xl' : 'text-base'"
>
{{ course.name }}
</h3>
<p class="text-sm dark:text-gray-400 text-gray-500 hidden lg:block flex-grow">
<p
class="dark:text-gray-400 text-gray-500 hidden lg:block flex-grow"
:class="'sponsor' in course && course.sponsor ? 'text-base' : 'text-sm'"
>
{{ course.description }}
</p>
<UBadge
Expand All @@ -60,6 +66,17 @@ defineOgImageComponent('Docs')
class="rounded-full"
/>
<UButton
v-if="'sponsor' in course && course.sponsor"
:to="course.url"
target="_blank"
trailing-icon="i-ph-arrow-right"
size="2xs"
color="green"
>
Discover course
</UButton>
<UButton
v-else
:to="course.url"
target="_blank"
trailing-icon="i-ph-arrow-right"
Expand Down
File renamed without changes.
File renamed without changes.
185 changes: 185 additions & 0 deletions app/plugins/kapa.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
const kapa = {
'key': 'kapa',
'src': 'https://widget.kapa.ai/kapa-widget.bundle.js',
'data-website-id': 'fb3af718-9db2-440d-9da9-14e6c5fca2aa',
// 'data-button-hide': true,
'data-project-name': 'Nuxt',
'data-project-color': '#00DC82',
'data-button-text-color': '#000000',
'data-project-logo': 'https://nuxt.com/assets/design-kit/icon-black.svg',
'data-modal-image': 'https://nuxt.com/assets/design-kit/icon-green.svg',
'data-button-padding': '0.5rem',
'data-button-width': '5.5rem',
'data-modal-disclaimer': 'This is a custom LLM for answering questions about Nuxt. Answers are based on the contents of the documentation, GitHub information and Stack Overflow articles. Please note that answers are generated by AI and may not be fully accurate, so please use your best judgement.',
'data-user-analytics-fingerprint-enabled': 'true',
'crossorigin': false
} as const

interface OnModalOpenArgs {
mode: 'search' | 'ai'
}

interface OnModalCloseArgs {
mode: 'search' | 'ai'
}

interface OnAskAIQuerySubmitArgs {
threadId: string | null
questionAnswerId: string
question: string
}

interface OnAskAIExampleQuerySubmitArgs {
threadId: string | null
questionAnswerId: string
question: string
}

interface OnAskAIAnswerCompletedArgs {
threadId: string
questionAnswerId: string
question: string
answer: string
conversation: { questionAnswerId: string, question: string, answer: string }[]
}

interface OnAskAIFeedbackSubmitArgs {
reaction: string
comment: {
issue: string
irrelevant: boolean
incorrect: boolean
unaddressed: boolean
}
threadId: string
questionAnswerId: string
question: string
answer: string
conversation: { questionAnswerId: string, question: string, answer: string }[]
}

interface OnAskAILinkClickArgs {
href: string
threadId: string
questionAnswerId: string
question: string
answer: string
}

interface OnAskAISourceClickArgs {
source: {
title: string
subtitle: string
url: string
}
threadId: string
questionAnswerId: string
question: string
answer: string
}

interface OnAskAIAnswerCopyArgs {
threadId: string
questionAnswerId: string
question: string
answer: string
}

interface OnAskAIGenerationStopArgs {
threadId: string | null
question: string
conversation: { questionAnswerId: string, question: string, answer: string }[]
}

interface OnAskAIConversationResetArgs {
threadId: string
conversation: { questionAnswerId: string, question: string, answer: string }[]
}

interface OnModeSwitchArgs {
mode: 'search' | 'ai'
}

interface OnSearchResultsCompletedArgs {
query: string
searchResults: { title: string, subtitle: string, url: string, sourceName: string }[]
}

interface OnSearchResultsShowMoreClickArgs {
query: string
searchResults: { title: string, subtitle: string, url: string, sourceName: string }[]
}

interface OnSearchResultClickArgs {
query: string
searchResult: { title: string, subtitle: string, url: string, sourceName: string }
rank: number
}

interface Kapa {
(event: 'onModalOpen', handler: (args: OnModalOpenArgs) => void): void
(event: 'onModalClose', handler: (args: OnModalCloseArgs) => void): void
(event: 'onAskAIQuerySubmit', handler: (args: OnAskAIQuerySubmitArgs) => void): void
(event: 'onAskAIExampleQuerySubmit', handler: (args: OnAskAIExampleQuerySubmitArgs) => void): void
(event: 'onAskAIAnswerCompleted', handler: (args: OnAskAIAnswerCompletedArgs) => void): void
(event: 'onAskAIFeedbackSubmit', handler: (args: OnAskAIFeedbackSubmitArgs) => void): void
(event: 'onAskAILinkClick', handler: (args: OnAskAILinkClickArgs) => void): void
(event: 'onAskAISourceClick', handler: (args: OnAskAISourceClickArgs) => void): void
(event: 'onAskAIAnswerCopy', handler: (args: OnAskAIAnswerCopyArgs) => void): void
(event: 'onAskAIGenerationStop', handler: (args: OnAskAIGenerationStopArgs) => void): void
(event: 'onAskAIConversationReset', handler: (args: OnAskAIConversationResetArgs) => void): void
(event: 'onModeSwitch', handler: (args: OnModeSwitchArgs) => void): void
(event: 'onSearchResultsCompleted', handler: (args: OnSearchResultsCompletedArgs) => void): void
(event: 'onSearchResultsShowMoreClick', handler: (args: OnSearchResultsShowMoreClickArgs) => void): void
(event: 'onSearchResultClick', handler: (args: OnSearchResultClickArgs) => void): void
}

declare global {
interface Window {
Kapa: Kapa
}
}

export default defineNuxtPlugin(() => {
const script = useScript<{ Kapa: Kapa }>(kapa, {
trigger: 'manual',
use() {
return { Kapa: window.Kapa }
}
})

return {
provide: {
kapa: {
async openModal(q) {
await script.load()
const button = await waitUntilSelector<HTMLButtonElement>('#kapa-widget-container button')
button?.click()
if (q) {
const input = await waitUntilSelector<HTMLInputElement>('#kapa-widget-portal .mantine-Textarea-input')
if (input) {
input.value = q
}
// await new Promise(resolve => setTimeout(resolve, 50))
// input.dispatchEvent(new Event('input', { bubbles: true }))
// document.querySelector('#kapa-widget-portal button.mantine-ActionIcon-root')?.click()
}
}
}
}
}
})

async function waitUntilSelector<T extends HTMLElement = HTMLElement>(selector: string) {
let i = 0

do {
const el = document.querySelector(selector)
if (el) {
return el as T
}
await new Promise(resolve => setTimeout(resolve, 10))
i++
} while (i < 200)
console.log('couldn\'t find selector', selector)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion content/0.index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -328,4 +328,4 @@ sections:
target: '_blank'
avatar:
src: 'https://ipx.nuxt.com/f_auto,s_40x40/gh_avatar/rijkvanzanten'
srcset: 'https://ipx.nuxt.com/f_auto,s_80x80/gh_avatar/rijkvanzanten 2x'
srcset: 'https://ipx.nuxt.com/f_auto,s_80x80/gh_avatar/rijkvanzanten 2x'
Loading

0 comments on commit 531d853

Please sign in to comment.