Skip to content

Commit db701d8

Browse files
authored
fix: adding loggout and docs support, improved email verification (#663)
1 parent 5cc240d commit db701d8

File tree

15 files changed

+688
-39
lines changed

15 files changed

+688
-39
lines changed

config/restify.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,41 @@
4545

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

48+
/*
49+
|--------------------------------------------------------------------------
50+
| User Email Verification URL
51+
|--------------------------------------------------------------------------
52+
|
53+
| This URL is used to redirect users after they click the email verification
54+
| link. The API will validate the verification and redirect to this frontend
55+
| URL with success/failure query parameters.
56+
|
57+
| Available placeholders:
58+
| {id} - User ID
59+
| {emailHash} - SHA1 hash of user's email
60+
|
61+
| Query parameters added by API:
62+
| ?success=true&message=Email verified successfully.
63+
| ?success=false&message=Invalid or expired verification link.
64+
|
65+
*/
4866
'user_verify_url' => env('FRONTEND_APP_URL').'/verify/{id}/{emailHash}',
4967

5068
'user_model' => "\App\Models\User",
69+
70+
/*
71+
|--------------------------------------------------------------------------
72+
| Token TTL (Time To Live)
73+
|--------------------------------------------------------------------------
74+
|
75+
| This value determines the number of minutes that authentication tokens
76+
| will be considered valid. After this time expires, users will need to
77+
| re-authenticate. Set to null for tokens that never expire.
78+
|
79+
| Default: null (never expires)
80+
|
81+
*/
82+
'token_ttl' => env('RESTIFY_TOKEN_TTL', null),
5183
],
5284

5385
/*

docs-v3/components/SearchModal.vue

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,14 @@
3838
placeholder="Search documentation..."
3939
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"
4040
@input="performSearch"
41+
@keyup="performSearch"
4142
@keydown.down.prevent="navigateResults('down')"
4243
@keydown.up.prevent="navigateResults('up')"
4344
@keydown.enter.prevent="selectResult"
45+
autocomplete="off"
46+
autocorrect="off"
47+
autocapitalize="off"
48+
spellcheck="false"
4449
/>
4550

4651
<div class="hidden sm:flex items-center space-x-2 text-xs text-gray-400 dark:text-gray-500">
@@ -225,7 +230,10 @@ const debounce = (fn: Function, delay: number) => {
225230
226231
// Search functionality
227232
const performSearch = debounce(async () => {
228-
if (!searchQuery.value.trim()) {
233+
const query = searchQuery.value?.trim()
234+
console.log('🔍 Search triggered with query:', query)
235+
236+
if (!query) {
229237
searchResults.value = []
230238
return
231239
}
@@ -234,7 +242,10 @@ const performSearch = debounce(async () => {
234242
selectedIndex.value = 0
235243
236244
try {
237-
searchResults.value = await searchContent(searchQuery.value)
245+
console.log('🔍 Performing search for:', query)
246+
const results = await searchContent(query)
247+
console.log('🔍 Search results:', results.length, 'items')
248+
searchResults.value = results
238249
} catch (error) {
239250
console.error('Search error:', error)
240251
searchResults.value = []
@@ -243,6 +254,25 @@ const performSearch = debounce(async () => {
243254
}
244255
}, 300)
245256
257+
// Also create immediate search for iOS
258+
const performImmediateSearch = async () => {
259+
const query = searchQuery.value?.trim()
260+
if (!query) return
261+
262+
console.log('🔍 Immediate search for iOS:', query)
263+
isSearching.value = true
264+
265+
try {
266+
const results = await searchContent(query)
267+
searchResults.value = results
268+
} catch (error) {
269+
console.error('Immediate search error:', error)
270+
searchResults.value = []
271+
} finally {
272+
isSearching.value = false
273+
}
274+
}
275+
246276
// Lifecycle
247277
onMounted(() => {
248278
document.addEventListener('keydown', handleKeydown)
@@ -265,6 +295,14 @@ watch(isOpen, (newIsOpen) => {
265295
}
266296
})
267297
298+
// Watch searchQuery changes for iOS devices where input events might not fire
299+
watch(searchQuery, (newQuery) => {
300+
console.log('🔍 Search query changed to:', newQuery)
301+
if (newQuery !== undefined) {
302+
performSearch()
303+
}
304+
}, { immediate: false })
305+
268306
// No need to expose methods since we're using global state
269307
</script>
270308

docs-v3/components/TheSidebar.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,17 @@ watch(isMobileMenuOpen, (isOpen) => {
144144
}
145145
})
146146
147-
// Collapsible sections state
147+
// Collapsible sections state - start with all sections collapsed
148148
const collapsedSections = ref<Set<string>>(new Set())
149149
150+
// Initialize all sections as collapsed when navigation sections are available
151+
onMounted(() => {
152+
if (navigationSections.value) {
153+
const allSectionTitles = navigationSections.value.map(section => section.title)
154+
collapsedSections.value = new Set(allSectionTitles)
155+
}
156+
})
157+
150158
// Toggle section visibility
151159
const toggleSection = (sectionTitle: string) => {
152160
if (collapsedSections.value.has(sectionTitle)) {

0 commit comments

Comments
 (0)