fix: Update upsplace URLs for future proof links
All checks were successful
Deploy to Staging / Build Images (push) Successful in 2m33s
Deploy to Staging / Deploy to Staging (push) Successful in 27s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
All checks were successful
Deploy to Staging / Build Images (push) Successful in 2m33s
Deploy to Staging / Deploy to Staging (push) Successful in 27s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
This commit is contained in:
@@ -1,55 +1,137 @@
|
|||||||
import { FeatureCard } from './FeatureCard';
|
import { FeatureCard } from './FeatureCard';
|
||||||
|
|
||||||
const features = [
|
type UnsplashFocalPoint = {
|
||||||
|
crop: 'focalpoint';
|
||||||
|
fpX: number; // 0.0 - 1.0
|
||||||
|
fpY: number; // 0.0 - 1.0
|
||||||
|
fpZ?: number; // zoom, optional
|
||||||
|
};
|
||||||
|
|
||||||
|
type UnsplashImageSpec = {
|
||||||
|
/** Unsplash image CDN photo id suffix, e.g. "1503376780353-7e6692767b70" */
|
||||||
|
photoId: string;
|
||||||
|
alt: string;
|
||||||
|
/** Defaults to 600x400 */
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
/** Defaults to 80 */
|
||||||
|
quality?: number;
|
||||||
|
/** Defaults to "crop" */
|
||||||
|
fit?: 'crop' | 'max' | 'fill' | 'fillmax' | 'min' | 'scale';
|
||||||
|
/** Optional focal-point crop tuning */
|
||||||
|
focal?: UnsplashFocalPoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Feature = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image: UnsplashImageSpec;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Centralize Unsplash identifiers so you only update them in one place if needed.
|
||||||
|
const UNSPLASH_IXLIB = 'rb-4.1.0';
|
||||||
|
const UNSPLASH_IXID = 'M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
|
||||||
|
|
||||||
|
function buildUnsplashUrl(spec: UnsplashImageSpec): string {
|
||||||
|
const {
|
||||||
|
photoId,
|
||||||
|
width = 600,
|
||||||
|
height = 400,
|
||||||
|
quality = 80,
|
||||||
|
fit = 'crop',
|
||||||
|
focal,
|
||||||
|
} = spec;
|
||||||
|
|
||||||
|
const url = new URL(`https://images.unsplash.com/photo-${photoId}`);
|
||||||
|
const params = url.searchParams;
|
||||||
|
|
||||||
|
// Unsplash / Imgix baseline params
|
||||||
|
params.set('ixlib', UNSPLASH_IXLIB);
|
||||||
|
params.set('ixid', UNSPLASH_IXID);
|
||||||
|
params.set('auto', 'format');
|
||||||
|
params.set('fit', fit);
|
||||||
|
params.set('w', String(width));
|
||||||
|
params.set('h', String(height));
|
||||||
|
params.set('q', String(quality));
|
||||||
|
|
||||||
|
// Optional focal-point cropping (great when the subject must remain centered)
|
||||||
|
if (focal) {
|
||||||
|
params.set('crop', focal.crop); // "focalpoint"
|
||||||
|
params.set('fp-x', String(focal.fpX));
|
||||||
|
params.set('fp-y', String(focal.fpY));
|
||||||
|
if (typeof focal.fpZ === 'number') params.set('fp-z', String(focal.fpZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const features: readonly Feature[] = [
|
||||||
{
|
{
|
||||||
title: 'Vehicle Management',
|
title: 'Vehicle Management',
|
||||||
description: 'Track all your vehicles in one centralized location with detailed information and history.',
|
description: 'Track all your vehicles in one centralized location with detailed information and history.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1503376780353-7e6692767b70?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Vehicle Management',
|
photoId: '1503376780353-7e6692767b70',
|
||||||
|
alt: 'Vehicle Management',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Fuel Log Tracking',
|
title: 'Fuel Log Tracking',
|
||||||
description: 'Monitor fuel consumption, costs, and efficiency across all your vehicles.',
|
description: 'Monitor fuel consumption, costs, and efficiency across all your vehicles.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1529369623266-f5264b696110?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Fuel Log Tracking',
|
photoId: '1529369623266-f5264b696110',
|
||||||
|
alt: 'Fuel Log Tracking',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Maintenance Records',
|
title: 'Maintenance Records',
|
||||||
description: 'Keep detailed maintenance logs and never miss scheduled service appointments.',
|
description: 'Keep detailed maintenance logs and never miss scheduled service appointments.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1486262715619-67b85e0b08d3?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Maintenance Records',
|
photoId: '1486262715619-67b85e0b08d3',
|
||||||
|
alt: 'Maintenance Records',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Document Storage',
|
title: 'Document Storage',
|
||||||
description: 'Store and organize all vehicle documents, receipts, and important paperwork.',
|
description: 'Store and organize all vehicle documents, receipts, and important paperwork.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Document Storage',
|
photoId: '1568605117036-5fe5e7bab0b7',
|
||||||
|
alt: 'Document Storage',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Fuel Stations',
|
title: 'Fuel Stations',
|
||||||
description: 'Find and track your favorite service stations and fuel locations.',
|
description: 'Find and track your favorite fuel locations. Community verified stations with Premium 93 Octane.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1572281335102-5f780686ee91?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&fit=crop&crop=focalpoint&fp-x=0.5&fp-y=0.6&q=80&auto=format&ixlib=rb-4.1.0&w=600&h=400',
|
image: {
|
||||||
imageAlt: 'Fuel Stations',
|
photoId: '1572281335102-5f780686ee91',
|
||||||
|
alt: 'Fuel Stations',
|
||||||
|
focal: { crop: 'focalpoint', fpX: 0.5, fpY: 0.6, fpZ: 1.35 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Reports & Analytics',
|
title: 'Reports & Analytics',
|
||||||
description: 'Generate detailed reports on costs, mileage, and vehicle performance.',
|
description: 'Generate detailed reports on costs, mileage, and vehicle performance.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Reports & Analytics',
|
photoId: '1551288049-bebda4e38f71',
|
||||||
|
alt: 'Reports & Analytics',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Reminders',
|
title: 'Reminders',
|
||||||
description: 'Set up automated reminders for maintenance, registration, and insurance renewals.',
|
description: 'Set up automated reminders for maintenance, registration, and insurance renewals.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1434494878577-86c23bcb06b9?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Reminders',
|
photoId: '1434494878577-86c23bcb06b9',
|
||||||
|
alt: 'Reminders',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Data Export',
|
title: 'Data Export',
|
||||||
description: 'Export your data in various formats for reporting and record keeping.',
|
description: 'Export your data in various formats for reporting and record keeping.',
|
||||||
imageSrc: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=600&h=400&fit=crop',
|
image: {
|
||||||
imageAlt: 'Data Export',
|
photoId: '1460925895917-afdab827c52f',
|
||||||
|
alt: 'Data Export',
|
||||||
},
|
},
|
||||||
];
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
export const FeaturesGrid = () => {
|
export const FeaturesGrid = () => {
|
||||||
return (
|
return (
|
||||||
@@ -64,14 +146,18 @@ export const FeaturesGrid = () => {
|
|||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
{features.map((feature) => (
|
{features.map((feature) => (
|
||||||
<FeatureCard key={feature.title} {...feature} />
|
<FeatureCard
|
||||||
|
key={feature.title}
|
||||||
|
title={feature.title}
|
||||||
|
description={feature.description}
|
||||||
|
imageSrc={buildUnsplashUrl(feature.image)}
|
||||||
|
imageAlt={feature.image.alt}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-center mt-12">
|
<div className="text-center mt-12">
|
||||||
<p className="text-lg text-titanio mb-6">
|
<p className="text-lg text-titanio mb-6">We are a cloud-based platform accessible anywhere, anytime.</p>
|
||||||
We are a cloud-based platform accessible anywhere, anytime.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user