Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions config/restify.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,41 @@

'password_reset_url' => env('FRONTEND_APP_URL').'/password/reset?token={token}&email={email}',

/*
|--------------------------------------------------------------------------
| User Email Verification URL
|--------------------------------------------------------------------------
|
| This URL is used to redirect users after they click the email verification
| link. The API will validate the verification and redirect to this frontend
| URL with success/failure query parameters.
|
| Available placeholders:
| {id} - User ID
| {emailHash} - SHA1 hash of user's email
|
| Query parameters added by API:
| ?success=true&message=Email verified successfully.
| ?success=false&message=Invalid or expired verification link.
|
*/
'user_verify_url' => env('FRONTEND_APP_URL').'/verify/{id}/{emailHash}',

'user_model' => "\App\Models\User",

/*
|--------------------------------------------------------------------------
| Token TTL (Time To Live)
|--------------------------------------------------------------------------
|
| This value determines the number of minutes that authentication tokens
| will be considered valid. After this time expires, users will need to
| re-authenticate. Set to null for tokens that never expire.
|
| Default: null (never expires)
|
*/
'token_ttl' => env('RESTIFY_TOKEN_TTL', null),
],

/*
Expand Down
42 changes: 40 additions & 2 deletions docs-v3/components/SearchModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@
placeholder="Search documentation..."
class="flex-1 bg-transparent text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 border-0 focus:ring-0 focus:outline-none text-lg"
@input="performSearch"
@keyup="performSearch"
@keydown.down.prevent="navigateResults('down')"
@keydown.up.prevent="navigateResults('up')"
@keydown.enter.prevent="selectResult"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>

<div class="hidden sm:flex items-center space-x-2 text-xs text-gray-400 dark:text-gray-500">
Expand Down Expand Up @@ -225,7 +230,10 @@ const debounce = (fn: Function, delay: number) => {

// Search functionality
const performSearch = debounce(async () => {
if (!searchQuery.value.trim()) {
const query = searchQuery.value?.trim()
console.log('🔍 Search triggered with query:', query)

if (!query) {
searchResults.value = []
return
}
Expand All @@ -234,7 +242,10 @@ const performSearch = debounce(async () => {
selectedIndex.value = 0

try {
searchResults.value = await searchContent(searchQuery.value)
console.log('🔍 Performing search for:', query)
const results = await searchContent(query)
console.log('🔍 Search results:', results.length, 'items')
searchResults.value = results
} catch (error) {
console.error('Search error:', error)
searchResults.value = []
Expand All @@ -243,6 +254,25 @@ const performSearch = debounce(async () => {
}
}, 300)

// Also create immediate search for iOS
const performImmediateSearch = async () => {
const query = searchQuery.value?.trim()
if (!query) return

console.log('🔍 Immediate search for iOS:', query)
isSearching.value = true

try {
const results = await searchContent(query)
searchResults.value = results
} catch (error) {
console.error('Immediate search error:', error)
searchResults.value = []
} finally {
isSearching.value = false
}
}

// Lifecycle
onMounted(() => {
document.addEventListener('keydown', handleKeydown)
Expand All @@ -265,6 +295,14 @@ watch(isOpen, (newIsOpen) => {
}
})

// Watch searchQuery changes for iOS devices where input events might not fire
watch(searchQuery, (newQuery) => {
console.log('🔍 Search query changed to:', newQuery)
if (newQuery !== undefined) {
performSearch()
}
}, { immediate: false })

// No need to expose methods since we're using global state
</script>

Expand Down
10 changes: 9 additions & 1 deletion docs-v3/components/TheSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,17 @@ watch(isMobileMenuOpen, (isOpen) => {
}
})

// Collapsible sections state
// Collapsible sections state - start with all sections collapsed
const collapsedSections = ref<Set<string>>(new Set())

// Initialize all sections as collapsed when navigation sections are available
onMounted(() => {
if (navigationSections.value) {
const allSectionTitles = navigationSections.value.map(section => section.title)
collapsedSections.value = new Set(allSectionTitles)
}
})

// Toggle section visibility
const toggleSection = (sectionTitle: string) => {
if (collapsedSections.value.has(sectionTitle)) {
Expand Down
Loading
Loading