Skip to content

Commit 39b47eb

Browse files
committed
fix React
1 parent d5700c1 commit 39b47eb

File tree

3 files changed

+158
-157
lines changed

3 files changed

+158
-157
lines changed

MyApp/Pages/React/Index.cshtml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,8 @@
450450
<script type="module">
451451
import { mount } from "app.mjs"
452452
import { ref, computed } from "vue"
453-
import Templates, { template } from "/pages/components/Templates.mjs"
454-
import ScreenshotsGallery from "/pages/components/ScreenshotsGallery.mjs"
453+
import Templates, { template } from "/posts/components/Templates.mjs"
454+
import ScreenshotsGallery from "/posts/components/ScreenshotsGallery.mjs"
455455
456456
export const Index = [
457457
template('react-vite', 'React Vite', 'ReactNative',['empty', 'tailwind']),
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
export default {
2+
props: {
3+
images: Object,
4+
gridClass: String,
5+
},
6+
template:`
7+
<div class="not-prose my-16">
8+
<!-- Gallery Grid -->
9+
<div :class="gridClass || 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8'">
10+
<div v-for="(imageUrl, title) in images" :key="title"
11+
@click="openLightbox(imageUrl, title)"
12+
class="group relative overflow-hidden rounded-xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:scale-[1.02] cursor-pointer bg-white dark:bg-gray-800">
13+
14+
<!-- Image Container with aspect ratio for 2048x2158 -->
15+
<div class="relative aspect-[2048/2158] overflow-hidden">
16+
<!-- Gradient overlay on hover -->
17+
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10"></div>
18+
19+
<!-- Image -->
20+
<img :src="imageUrl"
21+
:alt="title"
22+
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
23+
loading="lazy">
24+
25+
<!-- Title overlay -->
26+
<div class="absolute bottom-0 left-0 right-0 p-6 z-20 transform translate-y-full group-hover:translate-y-0 transition-transform duration-300">
27+
<h3 class="text-white text-lg font-semibold capitalize">{{ title }}</h3>
28+
<p class="text-gray-200 text-sm mt-1">Click to view full size</p>
29+
</div>
30+
31+
<!-- Zoom icon -->
32+
<div class="absolute top-4 right-4 z-20 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
33+
<div class="bg-white/90 dark:bg-gray-900/90 rounded-full p-2 shadow-lg">
34+
<svg class="w-5 h-5 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
35+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7"></path>
36+
</svg>
37+
</div>
38+
</div>
39+
</div>
40+
</div>
41+
</div>
42+
43+
<!-- Lightbox Modal -->
44+
<div v-if="lightboxOpen"
45+
@click="closeLightbox"
46+
class="fixed inset-0 z-50 flex items-center justify-center bg-black/95 backdrop-blur-sm p-4">
47+
48+
<!-- Close button -->
49+
<button @click="closeLightbox"
50+
class="absolute top-4 right-4 z-50 text-white hover:text-gray-300 transition-colors p-2 hover:bg-white/10 rounded-full">
51+
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
52+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
53+
</svg>
54+
</button>
55+
56+
<!-- Image title -->
57+
<div class="absolute top-4 left-4 z-50 bg-black/50 backdrop-blur-sm px-4 py-2 rounded-lg">
58+
<h3 class="text-white text-xl font-semibold capitalize">{{ currentTitle }}</h3>
59+
</div>
60+
61+
<!-- Image container -->
62+
<div @click.stop class="relative max-w-6xl max-h-[90vh] flex items-center justify-center">
63+
<img :src="currentImage"
64+
:alt="currentTitle"
65+
class="max-w-full max-h-[90vh] object-contain rounded-lg shadow-2xl">
66+
</div>
67+
68+
<!-- Navigation arrows (if multiple images) -->
69+
<button v-if="imageKeys.length > 1"
70+
@click.stop="previousImage"
71+
class="absolute left-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors p-3 hover:bg-white/10 rounded-full">
72+
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
73+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
74+
</svg>
75+
</button>
76+
77+
<button v-if="imageKeys.length > 1"
78+
@click.stop="nextImage"
79+
class="absolute right-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors p-3 hover:bg-white/10 rounded-full">
80+
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
81+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
82+
</svg>
83+
</button>
84+
85+
<!-- Image counter -->
86+
<div v-if="imageKeys.length > 1"
87+
class="absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/50 backdrop-blur-sm px-4 py-2 rounded-lg">
88+
<p class="text-white text-sm">{{ currentIndex + 1 }} / {{ imageKeys.length }}</p>
89+
</div>
90+
</div>
91+
</div>
92+
`,
93+
data() {
94+
return {
95+
lightboxOpen: false,
96+
currentImage: '',
97+
currentTitle: '',
98+
currentIndex: 0
99+
}
100+
},
101+
computed: {
102+
imageKeys() {
103+
return Object.keys(this.images)
104+
}
105+
},
106+
methods: {
107+
openLightbox(imageUrl, title) {
108+
this.currentImage = imageUrl
109+
this.currentTitle = title
110+
this.currentIndex = this.imageKeys.indexOf(title)
111+
this.lightboxOpen = true
112+
document.body.style.overflow = 'hidden'
113+
document.addEventListener('keydown', this.handleKeydown)
114+
},
115+
closeLightbox() {
116+
this.lightboxOpen = false
117+
document.body.style.overflow = ''
118+
document.removeEventListener('keydown', this.handleKeydown)
119+
},
120+
nextImage() {
121+
this.currentIndex = (this.currentIndex + 1) % this.imageKeys.length
122+
const key = this.imageKeys[this.currentIndex]
123+
this.currentImage = this.images[key]
124+
this.currentTitle = key
125+
},
126+
previousImage() {
127+
this.currentIndex = (this.currentIndex - 1 + this.imageKeys.length) % this.imageKeys.length
128+
const key = this.imageKeys[this.currentIndex]
129+
this.currentImage = this.images[key]
130+
this.currentTitle = key
131+
},
132+
handleKeydown(e) {
133+
if (!this.lightboxOpen) return
134+
135+
switch(e.key) {
136+
case 'Escape':
137+
this.closeLightbox()
138+
break
139+
case 'ArrowRight':
140+
if (this.imageKeys.length > 1) {
141+
this.nextImage()
142+
}
143+
break
144+
case 'ArrowLeft':
145+
if (this.imageKeys.length > 1) {
146+
this.previousImage()
147+
}
148+
break
149+
}
150+
}
151+
},
152+
beforeUnmount() {
153+
document.removeEventListener('keydown', this.handleKeydown)
154+
}
155+
}

MyApp/wwwroot/posts/react.mjs

Lines changed: 1 addition & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Templates, { Index } from "./components/Templates.mjs"
2+
import ScreenshotsGallery from "./components/ScreenshotsGallery.mjs"
23

34
const ReactTemplate = {
45
components: { Templates },
@@ -61,161 +62,6 @@ const ReactTemplate = {
6162
}
6263
}
6364

64-
const ScreenshotsGallery = {
65-
props: {
66-
images: Object
67-
},
68-
template:`
69-
<div class="not-prose my-16">
70-
<!-- Gallery Grid -->
71-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
72-
<div v-for="(imageUrl, title) in images" :key="title"
73-
@click="openLightbox(imageUrl, title)"
74-
class="group relative overflow-hidden rounded-xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:scale-[1.02] cursor-pointer bg-white dark:bg-gray-800">
75-
76-
<!-- Image Container with aspect ratio for 2048x2158 -->
77-
<div class="relative aspect-[2048/2158] overflow-hidden">
78-
<!-- Gradient overlay on hover -->
79-
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10"></div>
80-
81-
<!-- Image -->
82-
<img :src="imageUrl"
83-
:alt="title"
84-
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
85-
loading="lazy">
86-
87-
<!-- Title overlay -->
88-
<div class="absolute bottom-0 left-0 right-0 p-6 z-20 transform translate-y-full group-hover:translate-y-0 transition-transform duration-300">
89-
<h3 class="text-white text-lg font-semibold capitalize">{{ title }}</h3>
90-
<p class="text-gray-200 text-sm mt-1">Click to view full size</p>
91-
</div>
92-
93-
<!-- Zoom icon -->
94-
<div class="absolute top-4 right-4 z-20 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
95-
<div class="bg-white/90 dark:bg-gray-900/90 rounded-full p-2 shadow-lg">
96-
<svg class="w-5 h-5 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
97-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7"></path>
98-
</svg>
99-
</div>
100-
</div>
101-
</div>
102-
</div>
103-
</div>
104-
105-
<!-- Lightbox Modal -->
106-
<div v-if="lightboxOpen"
107-
@click="closeLightbox"
108-
class="fixed inset-0 z-50 flex items-center justify-center bg-black/95 backdrop-blur-sm p-4">
109-
110-
<!-- Close button -->
111-
<button @click="closeLightbox"
112-
class="absolute top-4 right-4 z-50 text-white hover:text-gray-300 transition-colors p-2 hover:bg-white/10 rounded-full">
113-
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
114-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
115-
</svg>
116-
</button>
117-
118-
<!-- Image title -->
119-
<div class="absolute top-4 left-4 z-50 bg-black/50 backdrop-blur-sm px-4 py-2 rounded-lg">
120-
<h3 class="text-white text-xl font-semibold capitalize">{{ currentTitle }}</h3>
121-
</div>
122-
123-
<!-- Image container -->
124-
<div @click.stop class="relative max-w-6xl max-h-[90vh] flex items-center justify-center">
125-
<img :src="currentImage"
126-
:alt="currentTitle"
127-
class="max-w-full max-h-[90vh] object-contain rounded-lg shadow-2xl">
128-
</div>
129-
130-
<!-- Navigation arrows (if multiple images) -->
131-
<button v-if="imageKeys.length > 1"
132-
@click.stop="previousImage"
133-
class="absolute left-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors p-3 hover:bg-white/10 rounded-full">
134-
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
135-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
136-
</svg>
137-
</button>
138-
139-
<button v-if="imageKeys.length > 1"
140-
@click.stop="nextImage"
141-
class="absolute right-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors p-3 hover:bg-white/10 rounded-full">
142-
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
143-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
144-
</svg>
145-
</button>
146-
147-
<!-- Image counter -->
148-
<div v-if="imageKeys.length > 1"
149-
class="absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/50 backdrop-blur-sm px-4 py-2 rounded-lg">
150-
<p class="text-white text-sm">{{ currentIndex + 1 }} / {{ imageKeys.length }}</p>
151-
</div>
152-
</div>
153-
</div>
154-
`,
155-
data() {
156-
return {
157-
lightboxOpen: false,
158-
currentImage: '',
159-
currentTitle: '',
160-
currentIndex: 0
161-
}
162-
},
163-
computed: {
164-
imageKeys() {
165-
return Object.keys(this.images)
166-
}
167-
},
168-
methods: {
169-
openLightbox(imageUrl, title) {
170-
this.currentImage = imageUrl
171-
this.currentTitle = title
172-
this.currentIndex = this.imageKeys.indexOf(title)
173-
this.lightboxOpen = true
174-
document.body.style.overflow = 'hidden'
175-
document.addEventListener('keydown', this.handleKeydown)
176-
},
177-
closeLightbox() {
178-
this.lightboxOpen = false
179-
document.body.style.overflow = ''
180-
document.removeEventListener('keydown', this.handleKeydown)
181-
},
182-
nextImage() {
183-
this.currentIndex = (this.currentIndex + 1) % this.imageKeys.length
184-
const key = this.imageKeys[this.currentIndex]
185-
this.currentImage = this.images[key]
186-
this.currentTitle = key
187-
},
188-
previousImage() {
189-
this.currentIndex = (this.currentIndex - 1 + this.imageKeys.length) % this.imageKeys.length
190-
const key = this.imageKeys[this.currentIndex]
191-
this.currentImage = this.images[key]
192-
this.currentTitle = key
193-
},
194-
handleKeydown(e) {
195-
if (!this.lightboxOpen) return
196-
197-
switch(e.key) {
198-
case 'Escape':
199-
this.closeLightbox()
200-
break
201-
case 'ArrowRight':
202-
if (this.imageKeys.length > 1) {
203-
this.nextImage()
204-
}
205-
break
206-
case 'ArrowLeft':
207-
if (this.imageKeys.length > 1) {
208-
this.previousImage()
209-
}
210-
break
211-
}
212-
}
213-
},
214-
beforeUnmount() {
215-
document.removeEventListener('keydown', this.handleKeydown)
216-
}
217-
}
218-
21965
export default {
22066
install(app) {
22167
},

0 commit comments

Comments
 (0)