astro-tractstack 2.0.0-rc.40 → 2.0.0-rc.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-tractstack",
3
- "version": "2.0.0-rc.40",
3
+ "version": "2.0.0-rc.42",
4
4
  "description": "Astro integration for TractStack - redeeming the web from boring experiences",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -153,7 +153,7 @@ const createdDate = created ? new Date(created) : new Date();
153
153
  <div
154
154
  class="text-myblue xs:flex-row my-2 flex flex-col items-center justify-center"
155
155
  >
156
- <div class="px-12 text-center text-2xl">
156
+ <div class="px-4 text-center text-2xl md:px-12">
157
157
  Copyright &#169; {createdDate.getFullYear()}{
158
158
  createdDate.getFullYear() !== new Date().getFullYear()
159
159
  ? `-${new Date().getFullYear()}`
@@ -164,9 +164,9 @@ const createdDate = created ? new Date(created) : new Date();
164
164
  </div>
165
165
  </div>
166
166
  <div
167
- class="text-myblue xs:flex-row my-2 flex flex-col items-center justify-center"
167
+ class="text-myblue my-2 flex flex-row items-center justify-center md:flex-col"
168
168
  >
169
- <div class="px-12 text-center text-lg">
169
+ <div class="px-4 text-center text-lg md:px-12">
170
170
  pressed with
171
171
  <a
172
172
  href="https://tractstack.com/?utm_source=tractstack&utm_medium=www&utm_campaign=community"
@@ -1,4 +1,10 @@
1
- import { useState, useEffect, useRef } from 'react';
1
+ import {
2
+ useState,
3
+ useEffect,
4
+ useRef,
5
+ type ChangeEvent,
6
+ type KeyboardEvent,
7
+ } from 'react';
2
8
  import { Dialog } from '@ark-ui/react/dialog';
3
9
  import { Portal } from '@ark-ui/react/portal';
4
10
  import { MagnifyingGlassIcon, XMarkIcon } from '@heroicons/react/24/outline';
@@ -49,7 +55,7 @@ export default function SearchModal({
49
55
  }
50
56
  }, [query, executeSearch, clearResults]);
51
57
 
52
- const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
58
+ const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
53
59
  setQuery(e.target.value);
54
60
  };
55
61
 
@@ -59,7 +65,7 @@ export default function SearchModal({
59
65
  onClose();
60
66
  };
61
67
 
62
- const handleKeyDown = (e: React.KeyboardEvent) => {
68
+ const handleKeyDown = (e: KeyboardEvent) => {
63
69
  if (e.key === 'Escape') {
64
70
  handleClose();
65
71
  }
@@ -72,17 +78,13 @@ export default function SearchModal({
72
78
  >
73
79
  <Portal>
74
80
  <Dialog.Backdrop className="fixed inset-0 z-50 bg-black bg-opacity-50 backdrop-blur-sm" />
75
- <Dialog.Positioner className="fixed inset-0 z-50 flex items-start justify-center p-4 pt-16">
81
+ <Dialog.Positioner className="fixed inset-0 z-50 mx-auto max-w-3xl p-2 pt-16 md:p-4">
76
82
  <Dialog.Content
77
- className="bg-mywhite w-full max-w-5xl overflow-hidden rounded-lg shadow-2xl"
78
- style={{ height: '80vh', display: 'flex', flexDirection: 'column' }}
83
+ className="bg-mywhite mx-auto w-full overflow-hidden rounded-lg shadow-2xl"
84
+ style={{ height: '80vh' }}
79
85
  >
80
86
  {/* Fixed Header */}
81
- <div
82
- className="flex items-center gap-4 border-b border-gray-200 p-6"
83
- style={{ flexShrink: 0 }}
84
- >
85
- <MagnifyingGlassIcon className="text-mydarkgrey h-6 w-6" />
87
+ <div className="relative w-full border-b border-gray-200 p-4">
86
88
  <input
87
89
  ref={inputRef}
88
90
  type="text"
@@ -90,11 +92,11 @@ export default function SearchModal({
90
92
  onChange={handleInputChange}
91
93
  onKeyDown={handleKeyDown}
92
94
  placeholder="Search content..."
93
- className="text-mydarkgrey flex-1 border-none bg-transparent px-4 text-xl placeholder-gray-500 outline-none"
95
+ className="text-mydarkgrey w-full border-none bg-transparent px-6 py-2 text-xl placeholder-gray-500 outline-none"
94
96
  />
95
97
  <button
96
98
  onClick={handleClose}
97
- className="text-mydarkgrey hover:text-myblue rounded-lg p-2 transition-colors hover:bg-gray-100"
99
+ className="text-mydarkgrey hover:text-myblue absolute right-4 top-6 rounded-lg p-2 transition-colors hover:bg-gray-100"
98
100
  aria-label="Close search"
99
101
  >
100
102
  <XMarkIcon className="h-6 w-6" />
@@ -102,9 +104,12 @@ export default function SearchModal({
102
104
  </div>
103
105
 
104
106
  {/* Scrollable Content Area */}
105
- <div className="overflow-y-auto" style={{ flex: 1 }}>
107
+ <div
108
+ className="w-full overflow-y-auto"
109
+ style={{ height: 'calc(80vh - 80px)' }}
110
+ >
106
111
  {query.length < 3 && (
107
- <div className="p-8 text-center text-gray-500">
112
+ <div className="w-full p-8 text-center text-gray-500">
108
113
  <MagnifyingGlassIcon className="mx-auto mb-4 h-16 w-16 text-gray-300" />
109
114
  <p className="text-lg">Search across all content</p>
110
115
  <p className="mt-2 text-sm">
@@ -115,14 +120,14 @@ export default function SearchModal({
115
120
  )}
116
121
 
117
122
  {query.length >= 3 && isLoading && (
118
- <div className="p-8 text-center">
123
+ <div className="w-full p-8 text-center">
119
124
  <div className="border-myblue inline-block h-8 w-8 animate-spin rounded-full border-b-2"></div>
120
125
  <p className="text-mydarkgrey mt-4">Searching...</p>
121
126
  </div>
122
127
  )}
123
128
 
124
129
  {query.length >= 3 && error && (
125
- <div className="p-8 text-center text-red-600">
130
+ <div className="w-full p-8 text-center text-red-600">
126
131
  <p>Search failed: {error}</p>
127
132
  <button
128
133
  onClick={() => executeSearch(query.trim())}
@@ -137,7 +142,7 @@ export default function SearchModal({
137
142
  !isLoading &&
138
143
  !error &&
139
144
  totalResults === 0 && (
140
- <div className="p-8 text-center text-gray-500">
145
+ <div className="w-full p-8 text-center text-gray-500">
141
146
  <p className="text-lg">No results found for "{query}"</p>
142
147
  <p className="mt-2 text-sm">
143
148
  Try different keywords or check your spelling
@@ -150,7 +150,7 @@ export default function SearchResults({
150
150
  return (
151
151
  <div className="p-6">
152
152
  <div className="mb-6">
153
- <h2 className="text-mydarkgrey text-lg font-semibold">
153
+ <h2 className="text-mydarkgrey text-lg font-bold">
154
154
  {allResultItems.length} result{allResultItems.length !== 1 ? 's' : ''}{' '}
155
155
  found
156
156
  </h2>
@@ -165,12 +165,12 @@ export default function SearchResults({
165
165
  {paginatedItems.map((item) => (
166
166
  <div
167
167
  key={item.id}
168
- className="hover:border-myblue rounded-lg border border-gray-200 p-4 transition-colors"
168
+ className="rounded-lg border border-gray-200 p-4 transition-colors hover:bg-gray-100"
169
169
  >
170
170
  <a href={item.url} onClick={onResultClick} className="group block">
171
171
  <div className="flex items-start gap-4">
172
172
  <div
173
- className="bg-mydarkgrey flex-shrink-0 overflow-hidden rounded-lg"
173
+ className="bg-mydarkgrey hidden flex-shrink-0 overflow-hidden rounded-lg md:block"
174
174
  style={{ width: '120px', height: '67.5px' }}
175
175
  >
176
176
  <img
@@ -185,7 +185,7 @@ export default function SearchResults({
185
185
  <div className="flex items-start justify-between gap-4">
186
186
  <div className="flex-1">
187
187
  <div className="mb-2">
188
- <h3 className="text-mydarkgrey group-hover:text-myblue line-clamp-2 font-semibold transition-colors">
188
+ <h3 className="text-mydarkgrey group-hover:text-myblue line-clamp-2 font-bold transition-colors">
189
189
  {item.title}
190
190
  </h3>
191
191
  </div>
@@ -219,7 +219,7 @@ export default function SearchResults({
219
219
  </p>
220
220
  </div>
221
221
 
222
- <div className="flex-shrink-0 text-right">
222
+ <div className="hidden flex-shrink-0 text-right md:block">
223
223
  <div className="mb-2">
224
224
  {getResultBadge(item.type, item.categorySlug)}
225
225
  </div>
@@ -13,6 +13,7 @@ export interface StoryData {
13
13
  menu: any;
14
14
  isHome: boolean;
15
15
  created: string;
16
+ socialImagePath?: string | null;
16
17
  }
17
18
 
18
19
  export async function getStoryData(
@@ -102,11 +102,17 @@ const brandConfig = await getBrandConfig(tenantId);
102
102
  if (!brandConfig.SITE_INIT) {
103
103
  return Astro.redirect('/storykeep');
104
104
  }
105
+
106
+ const ogImage =
107
+ typeof storyData.socialImagePath === `string`
108
+ ? storyData.socialImagePath
109
+ : undefined;
105
110
  ---
106
111
 
107
112
  <Layout
108
113
  title={storyfragmentTitle}
109
114
  slug={lookup || brandConfig.HOME_SLUG}
115
+ ogImage={ogImage}
110
116
  menu={storyData.menu || null}
111
117
  created={storyData.created}
112
118
  isContext={false}