309 lines
11 KiB
TypeScript
309 lines
11 KiB
TypeScript
// app/solutions/[industry]/page.tsx
|
|
|
|
import * as React from 'react';
|
|
import Link from 'next/link';
|
|
import { notFound } from 'next/navigation';
|
|
import { MoveUpRightIcon, DownloadIcon } from 'lucide-react';
|
|
|
|
import { Navbar } from '@workspace/ui/components/layout';
|
|
import { Footer } from '@workspace/ui/components/layout';
|
|
import { Container, Section, Grid } from '@workspace/ui/components/layout';
|
|
import { FeatureGrid } from '@workspace/ui/components/content/feature-grid';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@workspace/ui/components/ui';
|
|
import { Button } from '@workspace/ui/components/ui';
|
|
import { PlaceholderIcon } from '@workspace/ui/components/icons'; // Using placeholder for now
|
|
import Image from 'next/image';
|
|
|
|
// Types and mock data for industries and their specific details
|
|
type ProposedItem = { icon: React.ReactNode; title: string; description: string };
|
|
type Outcome = { metric: string; description: string };
|
|
type Industry = {
|
|
name: string;
|
|
title: string;
|
|
description: string;
|
|
painPoints: string[];
|
|
proposedStack: ProposedItem[];
|
|
migrationPlan: string[];
|
|
opsModel: string;
|
|
outcomes: Outcome[];
|
|
};
|
|
|
|
// In a real app, this would likely come from a CMS or database
|
|
const INDUSTRY_DATA: Record<string, Industry> = {
|
|
technology: {
|
|
name: 'Technology',
|
|
title: 'Cloud Alternatives for Technology Companies',
|
|
description:
|
|
'From SaaS startups to enterprise software, we help you scale efficiently without the cloud tax.',
|
|
painPoints: [
|
|
'High and unpredictable cloud bills that scale with user growth.',
|
|
'Vendor lock-in making it hard to switch providers or adopt hybrid models.',
|
|
'Complexity and overhead of managing cloud-native architectures.',
|
|
'Need for high performance and low latency for user-facing applications.',
|
|
],
|
|
proposedStack: [
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'Kubernetes (K3s/RKE2)',
|
|
description:
|
|
'Lightweight, certified Kubernetes for efficient container orchestration.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'PostgreSQL/MySQL',
|
|
description:
|
|
'Self-hosted, high-availability databases with point-in-time recovery.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'MinIO',
|
|
description: 'S3-compatible object storage for unstructured data.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'Nextcloud',
|
|
description: 'Private file sync, sharing, and collaboration platform.',
|
|
},
|
|
],
|
|
migrationPlan: [
|
|
'Audit current cloud spend and architecture.',
|
|
'Design a colocated Kubernetes cluster tailored to your workloads.',
|
|
'Migrate stateful services with zero downtime using blue-green deployments.',
|
|
'Implement CI/CD pipelines for automated testing and deployment.',
|
|
'Optimize for cost and performance post-migration.',
|
|
],
|
|
opsModel:
|
|
'We provide 24/7 monitoring, managed upgrades, and direct access to our SREs. You retain control over application configuration and scaling decisions.',
|
|
outcomes: [
|
|
{
|
|
metric: '60%',
|
|
description: 'Reduction in monthly infrastructure costs.',
|
|
},
|
|
{
|
|
metric: 'Sub-10ms',
|
|
description: 'Improved database query latency.',
|
|
},
|
|
{
|
|
metric: 'Zero',
|
|
description: 'Vendor lock-in with portable, open-source tools.',
|
|
},
|
|
],
|
|
},
|
|
legal: {
|
|
name: 'Legal',
|
|
title: 'Secure Infrastructure for Legal Firms',
|
|
description:
|
|
'Secure, private document management and collaboration environments with strict access controls.',
|
|
painPoints: [
|
|
'Stringent data privacy regulations (GDPR, CCPA) requiring data residency and control.',
|
|
'High cost of secure cloud storage and collaboration tools.',
|
|
'Risk of data breaches from third-party SaaS providers.',
|
|
'Need for comprehensive audit trails and access logging.',
|
|
],
|
|
proposedStack: [
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'Nextcloud',
|
|
description:
|
|
'Enterprise-grade file sync, sharing, and collaboration with full audit capabilities.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'OnlyOffice',
|
|
description:
|
|
'Private, self-hosted office suite for document editing and collaboration.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'Keycloak',
|
|
description:
|
|
'Centralized identity management with SAML/OIDC integration for existing directories.',
|
|
},
|
|
{
|
|
icon: <PlaceholderIcon className="size-5" />,
|
|
title: 'OpenSearch',
|
|
description:
|
|
'Self-hosted search and analytics engine for document discovery.',
|
|
},
|
|
],
|
|
migrationPlan: [
|
|
'Inventory and classify all documents and data flows.',
|
|
'Implement a secure, private Nextcloud instance with custom compliance policies.',
|
|
'Migrate existing document repositories with full version history.',
|
|
'Integrate with existing case management and time-tracking systems.',
|
|
'Train staff on new tools and security protocols.',
|
|
],
|
|
opsModel:
|
|
'We manage the underlying infrastructure, security patches, and backups. Your team manages user accounts, permissions, and document workflows.',
|
|
outcomes: [
|
|
{
|
|
metric: '100%',
|
|
description: 'Data sovereignty and compliance with legal regulations.',
|
|
},
|
|
{
|
|
metric: '$50k/year',
|
|
description: 'Savings vs. proprietary legal tech SaaS bundles.',
|
|
},
|
|
{
|
|
metric: 'Zero',
|
|
description: 'Third-party access to sensitive client data.',
|
|
},
|
|
],
|
|
},
|
|
// Add more industries here...
|
|
};
|
|
|
|
export default async function SolutionPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ industry: string }>;
|
|
}) {
|
|
const { industry } = await params;
|
|
const solution = INDUSTRY_DATA[industry];
|
|
|
|
if (!solution) {
|
|
notFound();
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col min-h-screen">
|
|
<Navbar />
|
|
<Section className="flex-grow">
|
|
<Container>
|
|
{/* Optional industry banner (drop /solutions/[industry]-hero.webp in public) */}
|
|
<div className="mb-8 rounded-sm border overflow-hidden bg-muted">
|
|
<div className="relative h-48 md:h-64 lg:h-72">
|
|
<Image
|
|
src={`/solutions/${industry}-hero.webp`}
|
|
alt=""
|
|
aria-hidden
|
|
fill
|
|
sizes="100vw"
|
|
className="object-cover"
|
|
priority={false}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="mb-8">
|
|
<Button variant="link" asChild className="px-0">
|
|
<Link href="/solutions">← All Solutions</Link>
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="text-center mb-12">
|
|
<h1 className="text-3xl md:text-4xl font-bold">{solution.title}</h1>
|
|
<p className="mt-4 text-muted-foreground max-w-2xl mx-auto">
|
|
{solution.description}
|
|
</p>
|
|
</div>
|
|
|
|
<Section>
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-6">Key Pain Points</h2>
|
|
<ul className="space-y-2">
|
|
{solution.painPoints.map((point: string, index: number) => (
|
|
<li key={index} className="flex items-start">
|
|
<span className="mr-2 text-primary">•</span>
|
|
<span>{point}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</Container>
|
|
</Section>
|
|
|
|
<Section background="muted">
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-6">Proposed Stack</h2>
|
|
<FeatureGrid
|
|
features={solution.proposedStack}
|
|
columns={{ initial: 1, sm: 2 }}
|
|
/>
|
|
</Container>
|
|
</Section>
|
|
|
|
<Section>
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-6">Migration Plan</h2>
|
|
<ol className="space-y-4">
|
|
{solution.migrationPlan.map((step: string, index: number) => (
|
|
<li key={index} className="flex items-start">
|
|
<span className="mr-3 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-sm font-bold">
|
|
{index + 1}
|
|
</span>
|
|
<span>{step}</span>
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</Container>
|
|
</Section>
|
|
|
|
<Section background="muted">
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-6">Operations Model</h2>
|
|
<p className="text-muted-foreground">{solution.opsModel}</p>
|
|
</Container>
|
|
</Section>
|
|
|
|
<Section>
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-6">Expected Outcomes</h2>
|
|
<Grid columns={{ initial: 1, sm: 3 }} gap="6">
|
|
{solution.outcomes.map(
|
|
(
|
|
outcome: { metric: string; description: string },
|
|
index: number,
|
|
) => (
|
|
<Card key={index}>
|
|
<CardHeader>
|
|
<CardTitle className="text-3xl font-bold">
|
|
{outcome.metric}
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<CardDescription>{outcome.description}</CardDescription>
|
|
</CardContent>
|
|
</Card>
|
|
),
|
|
)}
|
|
</Grid>
|
|
</Container>
|
|
</Section>
|
|
|
|
<Section background="muted" className="text-center">
|
|
<Container>
|
|
<h2 className="text-2xl font-bold mb-4">
|
|
Ready to transform your infrastructure?
|
|
</h2>
|
|
<p className="mb-6 text-muted-foreground max-w-2xl mx-auto">
|
|
Download our industry-specific blueprint or book a free
|
|
architecture call.
|
|
</p>
|
|
<div className="flex flex-col sm:flex-row gap-3 justify-center">
|
|
<Button asChild>
|
|
<a href={`/download-blueprint/${industry}`}>
|
|
<DownloadIcon className="mr-2 size-4" />
|
|
Download Blueprint
|
|
</a>
|
|
</Button>
|
|
<Button asChild variant="outline">
|
|
<a href="/contact">
|
|
Book Architecture Call
|
|
<MoveUpRightIcon className="ml-2 size-4" />
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
</Container>
|
|
</Section>
|
|
</Container>
|
|
</Section>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|