From d303c189a99b803fe1f85ba3fc30548546ea87be Mon Sep 17 00:00:00 2001 From: Marco Pedone Date: Tue, 12 May 2026 16:10:01 +0200 Subject: [PATCH] new guida --- .../src/components/how-it-works.tsx | 261 ++++++++++++++++++ apps/infoalloggi/src/pages/guida.tsx | 54 +++- 2 files changed, 310 insertions(+), 5 deletions(-) create mode 100644 apps/infoalloggi/src/components/how-it-works.tsx diff --git a/apps/infoalloggi/src/components/how-it-works.tsx b/apps/infoalloggi/src/components/how-it-works.tsx new file mode 100644 index 0000000..ef0f947 --- /dev/null +++ b/apps/infoalloggi/src/components/how-it-works.tsx @@ -0,0 +1,261 @@ +"use client"; + +import { domAnimation, LazyMotion, m } from "framer-motion"; +import type React from "react"; +import { cn } from "~/lib/utils"; + +interface CardProps { + number: string; + title: string; + description: string; + colorTheme?: "orange" | "blue" | "purple"; + className?: string; + rotate?: string; + colors?: { + bg: string; + text: string; + border: string; + }; +} + +const Card = ({ + number, + title, + description, + colorTheme = "blue", + className, + colors: customColors, +}: CardProps) => { + const defaultBgColors = { + orange: "bg-orange-50 dark:bg-orange-500/10", + blue: "bg-blue-50 dark:bg-blue-500/10", + purple: "bg-purple-50 dark:bg-purple-500/10", + }; + const defaultTextColors = { + orange: "text-orange-500 dark:text-orange-400", + blue: "text-blue-600 dark:text-blue-400", + purple: "text-purple-600 dark:text-purple-400", + }; + const defaultBorderColors = { + orange: "border-orange-100 dark:border-orange-500/20", + blue: "border-blue-100 dark:border-blue-500/20", + purple: "border-purple-100 dark:border-purple-500/20", + }; + + const bgColor = customColors?.bg || defaultBgColors[colorTheme]; + const textColor = customColors?.text || defaultTextColors[colorTheme]; + const borderColor = customColors?.border || defaultBorderColors[colorTheme]; + + return ( +
+
+
+ {number} +

+ {title} +

+

+ {description} +

+
+
+
+ ); +}; + +export interface Step { + title: string; + description: string; + colorTheme?: "orange" | "blue" | "purple"; + colors?: { + bg: string; + text: string; + border: string; + }; +} + +export interface StepPosition { + className?: string; +} + +export interface HowItWorksProps { + features?: Step[]; + className?: string; + stepPositions?: StepPosition[]; +} + +const DEFAULT_CARD_POSITIONS: StepPosition[] = [ + { + className: "md:absolute md:top-0 md:left-[15%] lg:left-[10%]", + }, + { + className: "md:absolute md:top-[210px] md:right-[15%] lg:right-[10%]", + }, + { + className: "md:absolute md:top-[450px] md:left-[15%] lg:left-[10%]", + }, + { + className: "md:absolute md:top-[680px] md:right-[10%] lg:right-[10%]", + }, + { + className: "md:absolute md:top-[910px] md:left-[15%] lg:left-[10%]", + }, +]; + +export default function HowItWorks({ + features, + className, + stepPositions, +}: HowItWorksProps) { + const defaultFeatures: Step[] = [ + { + title: "Create Account", + description: + "Sign up in minutes. Enter your details and verify your email to get started.", + colorTheme: "orange", + }, + { + title: "Verify Identity", + description: + "Complete your profile verification to ensure secure transactions and compliance.", + colorTheme: "blue", + }, + { + title: "Select Plan", + description: + "Choose from a variety of investment plans tailored to your financial goals.", + colorTheme: "purple", + }, + { + title: "Analyze & Invest", + description: + "Review returns and make your first investment with confidence.", + colorTheme: "orange", + }, + { + title: "Track Growth", + description: + "Monitor your portfolio in real-time and watch your wealth grow over time.", + colorTheme: "blue", + }, + ]; + + const data = features && features.length > 0 ? features : defaultFeatures; + const positions = stepPositions || DEFAULT_CARD_POSITIONS; + + let height = 1130; + if (data.length === 1) height = 400; + else if (data.length === 2) height = 450; + else if (data.length === 3) height = 800; + else if (data.length === 4) height = 900; + else height = 1130; + + return ( + +
+
+
+
+
+ +
+
+ {data.length > 1 && ( + + stroke + {(() => { + const pathD = data.reduce((acc, _, index) => { + if (index >= data.length - 1) return acc; + if (index === 0) + return "M 290 150 C 500 150, 550 270, 710 270"; // 1 -> 2 + if (index === 1) + return `${acc} C 850 270, 500 350, 290 450`; // 2 -> 3 + if (index === 2) + return `${acc} C 290 600, 550 720, 750 720`; // 3 -> 4 + if (index === 3) + return `${acc} C 950 720, 500 800, 290 850`; // 4 -> 5 + return acc; + }, ""); + return ( + + ); + })()} + + )} + + {data.map((step, index) => { + const position = positions[index % positions.length]; + if (!position) return null; + return ( + + ); + })} +
+
+
+
+ ); +} diff --git a/apps/infoalloggi/src/pages/guida.tsx b/apps/infoalloggi/src/pages/guida.tsx index 39fe07a..fe3231a 100644 --- a/apps/infoalloggi/src/pages/guida.tsx +++ b/apps/infoalloggi/src/pages/guida.tsx @@ -1,6 +1,6 @@ import type { NextPage } from "next"; import Head from "next/head"; -import { ComeFunziona } from "~/components/come_funziona"; +import HowItWorks from "~/components/how-it-works"; import { Accordion, AccordionContent, @@ -16,6 +16,49 @@ import { useTranslation } from "~/providers/I18nProvider"; */ const Guida: NextPage = () => { const { t } = useTranslation(); + //todo translation + const features = [ + { + title: "Esplora gli annunci", + description: + "In base a località, tipologia, prezzo, data di disponibilità e molte altre caratteristiche.", + colors: { + bg: "bg-orange-50 dark:bg-orange-500/10", + text: "text-orange-500 dark:text-orange-400", + border: "border-orange-100 dark:border-orange-500/20", + }, + }, + { + title: "Attiva il servizio", + description: + "Richiedi il servizio, ti invieremo un collegamento per completare la ricerca che abbiamo creato per te e acquistare il servizio.", + colors: { + bg: "bg-blue-50 dark:bg-blue-500/10", + text: "text-blue-600 dark:text-blue-400", + border: "border-blue-100 dark:border-blue-500/20", + }, + }, + { + title: "Visita le case", + description: + "Fissa appuntamenti direttamente con i proprietari per una visita. La trattativa è tra voi privati. Non c'è mediazione.", + colors: { + bg: "bg-purple-50 dark:bg-purple-500/10", + text: "text-purple-600 dark:text-purple-400", + border: "border-purple-100 dark:border-purple-500/20", + }, + }, + { + title: "Contratto di affitto", + description: + "Procederemo alla stesura del contratto di locazione in base agli accordi che hai trovato con il propritario.", + colors: { + bg: "bg-green-50 dark:bg-green-500/10", + text: "text-green-500 dark:text-green-400", + border: "border-green-100 dark:border-green-500/20", + }, + }, + ]; return ( <> @@ -23,12 +66,13 @@ const Guida: NextPage = () => { {t.heads.guida_titolo} -
+
{t.guida} - + {/* */} +
@@ -51,8 +95,8 @@ const FAQSection = () => { } return ( -
-
+
+