Skip to content

Commit 43589ed

Browse files
committed
server image updates
1 parent 7bb08d9 commit 43589ed

File tree

6 files changed

+177
-4
lines changed

6 files changed

+177
-4
lines changed
95.1 KB
Loading
129 KB
Loading
65.9 KB
Loading
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
interface Props {
3+
src: string; // URL string instead of imported asset
4+
alt: string;
5+
width?: number | string;
6+
height?: number | string;
7+
className?: string;
8+
loading?: "lazy" | "eager";
9+
decoding?: "async" | "sync" | "auto";
10+
sizes?: string;
11+
quality?: number;
12+
format?: "avif" | "webp" | "jpeg" | "jpg" | "png" | "gif";
13+
// Additional HTML img attributes
14+
crossorigin?: "anonymous" | "use-credentials";
15+
referrerpolicy?:
16+
| "no-referrer"
17+
| "no-referrer-when-downgrade"
18+
| "origin"
19+
| "origin-when-cross-origin"
20+
| "same-origin"
21+
| "strict-origin"
22+
| "strict-origin-when-cross-origin"
23+
| "unsafe-url";
24+
// Style props
25+
objectFit?: "contain" | "cover" | "fill" | "none" | "scale-down";
26+
objectPosition?: string;
27+
}
28+
29+
const {
30+
src,
31+
alt,
32+
width,
33+
height,
34+
className = "",
35+
loading = "lazy",
36+
decoding = "async",
37+
sizes,
38+
quality,
39+
format,
40+
crossorigin,
41+
referrerpolicy,
42+
objectFit,
43+
objectPosition,
44+
} = Astro.props;
45+
46+
// Build style object
47+
const imageStyles: Record<string, string> = {};
48+
if (width && typeof width === "number") imageStyles.width = `${width}px`;
49+
if (width && typeof width === "string") imageStyles.width = width;
50+
if (height && typeof height === "number") imageStyles.height = `${height}px`;
51+
if (height && typeof height === "string") imageStyles.height = height;
52+
if (objectFit) imageStyles.objectFit = objectFit;
53+
if (objectPosition) imageStyles.objectPosition = objectPosition;
54+
55+
// Function to check if URL is external
56+
function isExternalUrl(url: string): boolean {
57+
return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//");
58+
}
59+
60+
// Function to optimize image URL based on format and quality (for external images)
61+
function optimizeImageUrl(url: string, format?: string, quality?: number): string {
62+
// For external URLs, we can't optimize them directly
63+
// But we can add query parameters if the service supports it
64+
// This is a placeholder for future enhancement
65+
return url;
66+
}
67+
68+
// Process the source URL
69+
const isExternal = isExternalUrl(src);
70+
const processedSrc = isExternal ? optimizeImageUrl(src, format, quality) : src;
71+
72+
// Build srcset for responsive images (basic implementation)
73+
function buildSrcSet(baseSrc: string): string | undefined {
74+
if (!sizes || isExternal) return undefined;
75+
76+
// For internal images, we could generate different sizes
77+
// This is a simplified version - in a real implementation you might
78+
// want to use Astro's image optimization service
79+
return undefined;
80+
}
81+
82+
const srcset = buildSrcSet(processedSrc);
83+
---
84+
85+
<img
86+
src={processedSrc}
87+
alt={alt}
88+
class={`image-url ${className}`}
89+
style={imageStyles}
90+
loading={loading}
91+
decoding={decoding}
92+
sizes={sizes}
93+
srcset={srcset}
94+
crossorigin={crossorigin}
95+
referrerpolicy={referrerpolicy}
96+
{...(width && typeof width === "number" && { width })}
97+
{...(height && typeof height === "number" && { height })}
98+
/>
99+
100+
<style lang="scss">
101+
@use "../../styles/mixins" as *;
102+
103+
.image-url {
104+
max-width: 100%;
105+
height: auto;
106+
display: block;
107+
108+
// Default styling similar to Astro's Image component
109+
&:not([width]):not([height]) {
110+
width: 100%;
111+
height: auto;
112+
}
113+
114+
// Responsive behavior
115+
@include break-down(md) {
116+
max-width: 100%;
117+
height: auto;
118+
}
119+
120+
// Loading states
121+
&[loading="lazy"] {
122+
// Add any lazy loading specific styles if needed
123+
}
124+
125+
&[loading="eager"] {
126+
// Add any eager loading specific styles if needed
127+
}
128+
129+
// Object fit styles when specified
130+
&[style*="object-fit"] {
131+
object-fit: inherit; // Will be overridden by inline styles
132+
}
133+
134+
// Error handling - show placeholder if image fails to load
135+
&[alt]:after {
136+
content: attr(alt);
137+
position: absolute;
138+
top: 50%;
139+
left: 50%;
140+
transform: translate(-50%, -50%);
141+
padding: 1rem;
142+
background: var(--surface-nav-bg, #f5f5f5);
143+
border: 1px solid var(--border-color, #ddd);
144+
border-radius: 4px;
145+
font-size: 0.875rem;
146+
color: var(--text-body-secondary, #666);
147+
text-align: center;
148+
display: none;
149+
}
150+
151+
&:not([src]),
152+
&[src=""] {
153+
&:after {
154+
display: block;
155+
}
156+
}
157+
}
158+
159+
// Dark theme support
160+
.theme-dark .image-url {
161+
&[alt]:after {
162+
background: var(--surface-nav-bg-dark, #2a2a2a);
163+
border-color: var(--border-color-dark, #444);
164+
color: var(--text-body-secondary-dark, #ccc);
165+
}
166+
}
167+
</style>
168+

src/components/server/ServerSidebar.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ const { sections, title = "Main Features" } = Astro.props;
6565

6666
a {
6767
display: block;
68-
padding: 0.5rem 1rem;
68+
padding: 0.2rem 0.5rem;
6969
text-decoration: none;
7070
color: var(--text-body-primary);
7171
transition: all 0.2s ease;
7272
@include typography(menu);
73-
font-size: calc(1rem * var(--font-scale-factor));
73+
font-size: calc(0.9rem * var(--font-scale-factor));
7474

7575
&:hover {
7676
background: var(--surface-main-primary);

src/pages/server.astro

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Image from "astro/components/Image.astro";
1717
import YouTubeVideo from "../components/video/YouTubeVideo.astro";
1818
import CTASection from "../components/CTASection.astro";
1919
import ImageCarousel from "../components/image/ImageCarousel.astro";
20+
import ImageURL from "../components/image/ImageURL.astro"
2021
2122
const testimonialsImportData = await Astro.glob("../data/home/testimonials/**/*.md");
2223
@@ -118,7 +119,11 @@ const sections = [
118119
</div>
119120

120121
<div slot="right">
121-
<ImageCarousel src="/images/data/api.png,/images/data/enrollment-screen.png,/images/data/vision.png" alt="VPN locations dashboard and user details" interval={3} autoplay={true} />
122+
<ImageCarousel
123+
src="/images/features/Manage multiple VPN1.png,/images/features/Manage multiple VPN2.png" alt="VPN locations dashboard and user details"
124+
interval={3}
125+
autoplay={true}
126+
/>
122127
</div>
123128
</FlexibleSection>
124129

@@ -129,7 +134,7 @@ const sections = [
129134
theme="light"
130135
>
131136
<div slot="left">
132-
<Image src={enrollment} alt="Enrollment with Google login" />
137+
<ImageURL src="/images/features/Multiple instances - desktop.png" alt="Enrollment with Google login" />
133138
</div>
134139

135140
<div slot="right">

0 commit comments

Comments
 (0)