Skip to content

Commit 9402e4d

Browse files
committed
feat: Constructo page improvements
1 parent bb81b10 commit 9402e4d

File tree

11 files changed

+459
-309
lines changed

11 files changed

+459
-309
lines changed

src/components/CodeBlock.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const CodeBlock = ({
3636
});
3737
setTimeout(() => setCopied(false), 2000);
3838
} catch (err) {
39+
// eslint-disable-next-line no-console
40+
console.error(err);
3941
toast({
4042
description: "Erro ao copiar código",
4143
variant: "destructive",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { CheckCircle } from "lucide-react";
2+
3+
interface BenefitItemProps {
4+
title: string;
5+
description: string;
6+
}
7+
8+
const BenefitItem = ({ title, description }: BenefitItemProps) => {
9+
return (
10+
<div className="flex items-start space-x-4">
11+
<CheckCircle className="w-6 h-6 text-success mt-1 flex-shrink-0" />
12+
<div>
13+
<h3 className="font-semibold mb-2">{title}</h3>
14+
<p className="text-muted-foreground">{description}</p>
15+
</div>
16+
</div>
17+
);
18+
};
19+
20+
export default BenefitItem;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { BookOpen } from "lucide-react";
2+
import { Button } from "@/components/ui/button.tsx";
3+
import Hero from "@/components/Hero.tsx";
4+
import BenefitItem from "./BenefitItem.tsx";
5+
6+
interface Benefit {
7+
title: string;
8+
description: string;
9+
}
10+
11+
interface BenefitsProps {
12+
benefits: Benefit[];
13+
onDocsClick: () => void;
14+
}
15+
16+
const Benefits = ({ benefits, onDocsClick }: BenefitsProps) => {
17+
return (
18+
<Hero>
19+
<div className="text-center mb-16">
20+
<h2 className="text-4xl font-bold mb-4">Por que Constructo?</h2>
21+
<p className="text-xl text-muted-foreground">
22+
Vantagens que fazem a diferença no seu desenvolvimento
23+
</p>
24+
</div>
25+
26+
<div className="grid md:grid-cols-2 gap-8 max-w-4xl mx-auto">
27+
{benefits.map((benefit, index) => (
28+
<BenefitItem key={index} title={benefit.title} description={benefit.description} />
29+
))}
30+
</div>
31+
32+
<div className="flex items-center justify-center space-x-4 pt-10">
33+
<Button
34+
onClick={onDocsClick}
35+
size="lg"
36+
className="bg-gradient-constructo text-constructo-foreground transition-all hover:shadow-glow gap-2"
37+
>
38+
<BookOpen className="w-4 h-4" />
39+
Primeiros Passos
40+
</Button>
41+
</div>
42+
</Hero>
43+
);
44+
};
45+
46+
export default Benefits;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs.tsx";
2+
import CodeTab from "./CodeTab.tsx";
3+
4+
interface CodeExample {
5+
id: string;
6+
title: string;
7+
description: string;
8+
code: string;
9+
}
10+
11+
interface CodeExamplesProps {
12+
examples: CodeExample[];
13+
}
14+
15+
const CodeExamples = ({ examples }: CodeExamplesProps) => {
16+
return (
17+
<section className="py-20 px-6 bg-card/30">
18+
<div className="container mx-auto">
19+
<div className="text-center mb-12">
20+
<h2 className="text-3xl font-bold mb-4">Exemplos Práticos</h2>
21+
<p className="text-muted-foreground">
22+
Veja como usar o Constructo em diferentes cenários
23+
</p>
24+
</div>
25+
26+
<div className="max-w-6xl mx-auto">
27+
<Tabs defaultValue={examples[0]?.id} className="w-full">
28+
<TabsList>
29+
{examples.map(example => (
30+
<TabsTrigger key={example.id} value={example.id}>
31+
{example.title}
32+
</TabsTrigger>
33+
))}
34+
</TabsList>
35+
36+
{examples.map(example => (
37+
<TabsContent key={example.id} value={example.id}>
38+
<CodeTab
39+
title={example.title}
40+
description={example.description}
41+
code={example.code}
42+
/>
43+
</TabsContent>
44+
))}
45+
</Tabs>
46+
</div>
47+
</div>
48+
</section>
49+
);
50+
};
51+
52+
export default CodeExamples;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
Card,
3+
CardContent,
4+
CardDescription,
5+
CardHeader,
6+
CardTitle,
7+
} from "@/components/ui/card.tsx";
8+
import CodeBlock from "@/components/CodeBlock.tsx";
9+
import { ReactNode } from "react";
10+
11+
interface CodeTabProps {
12+
title: string;
13+
description: string;
14+
code: string;
15+
language?: string;
16+
}
17+
18+
const CodeTab = ({ title, description, code, language = "php" }: CodeTabProps) => {
19+
return (
20+
<Card>
21+
<CardHeader>
22+
<CardTitle>{title}</CardTitle>
23+
<CardDescription>{description}</CardDescription>
24+
</CardHeader>
25+
<CardContent>
26+
<CodeBlock language={language}>{code}</CodeBlock>
27+
</CardContent>
28+
</Card>
29+
);
30+
};
31+
32+
export default CodeTab;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Card } from "@/components/ui/card.tsx";
2+
import { ReactNode } from "react";
3+
import { Soon } from "@/components/Soon.tsx";
4+
5+
interface FeatureCardProps {
6+
icon: ReactNode;
7+
title: string;
8+
description: string;
9+
soon?: boolean;
10+
}
11+
12+
const FeatureCard = ({ icon, title, description, soon = false }: FeatureCardProps) => {
13+
return (
14+
<Card className="p-6 hover:shadow-elegant transition-all duration-300 hover:scale-105">
15+
<div className="flex items-center gap-2 mb-4">
16+
<div className="w-12 h-12 bg-gradient-constructo rounded-xl flex items-center justify-center">
17+
{icon}
18+
</div>
19+
{soon && <Soon />}
20+
</div>
21+
<h3 className="text-xl font-semibold mb-3">{title}</h3>
22+
<p className="text-muted-foreground">{description}</p>
23+
</Card>
24+
);
25+
};
26+
27+
export default FeatureCard;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ReactNode } from "react";
2+
import FeatureCard from "./FeatureCard.tsx";
3+
4+
interface Feature {
5+
icon: ReactNode;
6+
title: string;
7+
description: string;
8+
soon?: boolean;
9+
}
10+
11+
interface FeaturesProps {
12+
features: Feature[];
13+
}
14+
15+
const Features = ({ features }: FeaturesProps) => {
16+
return (
17+
<section className="py-20 px-6">
18+
<div className="container mx-auto">
19+
<div className="text-center mb-16">
20+
<h2 className="text-4xl font-bold mb-4">Recursos Principais</h2>
21+
<p className="text-xl text-muted-foreground">
22+
Tudo que você precisa para construir aplicações PHP modernas
23+
</p>
24+
</div>
25+
26+
<div className="grid md:grid-cols-3 gap-8">
27+
{features.map((feature, index) => (
28+
<FeatureCard
29+
key={index}
30+
icon={feature.icon}
31+
title={feature.title}
32+
description={feature.description}
33+
soon={feature.soon}
34+
/>
35+
))}
36+
</div>
37+
</div>
38+
</section>
39+
);
40+
};
41+
42+
export default Features;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { BookOpen, Package } from "lucide-react";
2+
import { Button } from "@/components/ui/button.tsx";
3+
import CodeBlock from "@/components/CodeBlock.tsx";
4+
5+
interface InstallationProps {
6+
onPackagistClick: () => void;
7+
onDocsClick: () => void;
8+
}
9+
10+
const Installation = ({ onPackagistClick, onDocsClick }: InstallationProps) => {
11+
return (
12+
<section className="py-16 px-6 bg-card/30">
13+
<div className="container mx-auto">
14+
<div className="text-center mb-12">
15+
<h2 className="text-3xl font-bold mb-4">Instalação Rápida</h2>
16+
<p className="text-muted-foreground">Comece a usar o Constructo em segundos</p>
17+
</div>
18+
19+
<div className="max-w-2xl mx-auto space-y-4">
20+
<CodeBlock language="bash" size="md">
21+
composer require devitools/constructo
22+
</CodeBlock>
23+
24+
<div className="text-center flex flex-col sm:flex-row gap-3 justify-center">
25+
<Button variant="outline" onClick={onPackagistClick} className="gap-2">
26+
<Package className="w-4 h-4" />
27+
Ver no Packagist
28+
</Button>
29+
<Button
30+
onClick={onDocsClick}
31+
className="bg-gradient-constructo text-constructo-foreground transition-all hover:shadow-glow gap-2"
32+
>
33+
<BookOpen className="w-4 h-4" />
34+
Primeiros Passos
35+
</Button>
36+
</div>
37+
</div>
38+
</div>
39+
</section>
40+
);
41+
};
42+
43+
export default Installation;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Card } from "@/components/ui/card.tsx";
2+
import { CheckCircle } from "lucide-react";
3+
import { ReactNode } from "react";
4+
5+
interface UseCaseCardProps {
6+
icon: ReactNode;
7+
title: string;
8+
description: string;
9+
benefits: string[];
10+
}
11+
12+
const UseCaseCard = ({ icon, title, description, benefits }: UseCaseCardProps) => {
13+
return (
14+
<Card className="p-6 hover:shadow-elegant transition-all duration-300">
15+
<div className="w-16 h-16 bg-gradient-constructo rounded-2xl mb-6 flex items-center justify-center">
16+
{icon}
17+
</div>
18+
<h3 className="text-xl font-semibold mb-4">{title}</h3>
19+
<p className="text-muted-foreground mb-4">{description}</p>
20+
<ul className="space-y-2">
21+
{benefits.map((benefit, i) => (
22+
<li key={i} className="flex items-center text-sm">
23+
<CheckCircle className="w-4 h-4 text-success mr-2 flex-shrink-0" />
24+
{benefit}
25+
</li>
26+
))}
27+
</ul>
28+
</Card>
29+
);
30+
};
31+
32+
export default UseCaseCard;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { ReactNode } from "react";
2+
import UseCaseCard from "./UseCaseCard.tsx";
3+
4+
interface UseCase {
5+
icon: ReactNode;
6+
title: string;
7+
description: string;
8+
benefits: string[];
9+
}
10+
11+
interface UseCasesProps {
12+
useCases: UseCase[];
13+
}
14+
15+
const UseCases = ({ useCases }: UseCasesProps) => {
16+
return (
17+
<section className="py-20 px-6">
18+
<div className="container mx-auto">
19+
<div className="text-center mb-16">
20+
<h2 className="text-4xl font-bold mb-4">Casos de Uso</h2>
21+
<p className="text-xl text-muted-foreground">Quando usar o Constructo em seus projetos</p>
22+
</div>
23+
24+
<div className="grid lg:grid-cols-3 gap-8">
25+
{useCases.map((useCase, index) => (
26+
<UseCaseCard
27+
key={index}
28+
icon={useCase.icon}
29+
title={useCase.title}
30+
description={useCase.description}
31+
benefits={useCase.benefits}
32+
/>
33+
))}
34+
</div>
35+
</div>
36+
</section>
37+
);
38+
};
39+
40+
export default UseCases;

0 commit comments

Comments
 (0)