fixed CV stuff

This commit is contained in:
2025-08-07 15:15:37 +02:00
parent 5429a17ed6
commit 40796c2e88
5 changed files with 14 additions and 287 deletions
+14 -12
View File
@@ -173,11 +173,11 @@ const Portfolio = () => {
const education = [ const education = [
{ {
id: 1, id: 1,
institution: 'USI Università della Svizzera italiana, Lugano', institution: 'Scuola cantonale di commercio, Bellinzona',
degree: "Bachelor's Degree in Economics (English Stream)", degree: 'Maturità Cantonale & AFC Economics',
period: 'September 2024 - Present', period: 'September 2018 - June 2022',
status: 'Current', status: '4.5/6 (Maturità), 5/6 (AFC)',
description: 'Pursuing coursework in microeconomics, macroeconomics, statistics, accounting, and quantitative methods with particular interest in finance.' description: 'Completed secondary education with focus on economics and business administration.'
}, },
{ {
id: 2, id: 2,
@@ -189,11 +189,11 @@ const Portfolio = () => {
}, },
{ {
id: 3, id: 3,
institution: 'Scuola cantonale di commercio, Bellinzona', institution: 'USI Università della Svizzera italiana, Lugano',
degree: 'Maturità Cantonale & AFC Economics', degree: "Bachelor's Degree in Economics (English Stream)",
period: 'September 2018 - June 2022', period: 'September 2024 - Present',
status: '4.5/6 (Maturità), 5/6 (AFC)', status: 'Current',
description: 'Completed secondary education with focus on economics and business administration.' description: 'Pursuing coursework in microeconomics, macroeconomics, statistics, accounting, and quantitative methods with particular interest in finance.'
} }
]; ];
@@ -901,7 +901,9 @@ const Portfolio = () => {
{/* Download CV Button */} {/* Download CV Button */}
<div className="mb-8"> <div className="mb-8">
<button <a
href="/Pietro_Quintavalle_CV.pdf"
download="Pietro_Quintavalle_CV.pdf"
className="inline-flex items-center px-6 py-3 rounded-lg font-medium transition-colors hover:opacity-90" className="inline-flex items-center px-6 py-3 rounded-lg font-medium transition-colors hover:opacity-90"
style={{ style={{
backgroundColor: nordColors.accent, backgroundColor: nordColors.accent,
@@ -912,7 +914,7 @@ const Portfolio = () => {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg> </svg>
Download CV Download CV
</button> </a>
</div> </div>
</div> </div>
</section> </section>
-59
View File
@@ -1,59 +0,0 @@
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/ui/timeline"
const items = [
{
id: 1,
date: "Mar 15, 2024",
title: "Project Kickoff",
description: "Initial team meeting.",
},
{
id: 2,
date: "Mar 22, 2024",
title: "Design Phase",
description: "Completed wireframes.",
},
{
id: 3,
date: "Apr 5, 2024",
title: "Development Sprint",
description: "Backend development.",
},
{
id: 4,
date: "Apr 19, 2024",
title: "Testing & Deployment",
description: "Performance optimization.",
},
]
export default function Component() {
return (
<Timeline defaultValue={3} orientation="horizontal">
{items.map((item) => (
<TimelineItem
key={item.id}
step={item.id}
className="group-data-[orientation=horizontal]/timeline:mt-0"
>
<TimelineHeader>
<TimelineSeparator className="group-data-[orientation=horizontal]/timeline:top-8" />
<TimelineDate className="mb-10">{item.date}</TimelineDate>
<TimelineTitle>{item.title}</TimelineTitle>
<TimelineIndicator className="group-data-[orientation=horizontal]/timeline:top-8" />
</TimelineHeader>
<TimelineContent>{item.description}</TimelineContent>
</TimelineItem>
))}
</Timeline>
)
}
-210
View File
@@ -1,210 +0,0 @@
"use client"
import * as React from "react"
import { Slot } from "radix-ui"
import { cn } from "@/lib/utils"
// Types
type TimelineContextValue = {
activeStep: number
setActiveStep: (step: number) => void
}
// Context
const TimelineContext = React.createContext<TimelineContextValue | undefined>(
undefined
)
const useTimeline = () => {
const context = React.useContext(TimelineContext)
if (!context) {
throw new Error("useTimeline must be used within a Timeline")
}
return context
}
// Components
interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
defaultValue?: number
value?: number
onValueChange?: (value: number) => void
orientation?: "horizontal" | "vertical"
}
function Timeline({
defaultValue = 1,
value,
onValueChange,
orientation = "vertical",
className,
...props
}: TimelineProps) {
const [activeStep, setInternalStep] = React.useState(defaultValue)
const setActiveStep = React.useCallback(
(step: number) => {
if (value === undefined) {
setInternalStep(step)
}
onValueChange?.(step)
},
[value, onValueChange]
)
const currentStep = value ?? activeStep
return (
<TimelineContext.Provider
value={{ activeStep: currentStep, setActiveStep }}
>
<div
data-slot="timeline"
className={cn(
"group/timeline flex data-[orientation=horizontal]:w-full data-[orientation=horizontal]:flex-row data-[orientation=vertical]:flex-col",
className
)}
data-orientation={orientation}
{...props}
/>
</TimelineContext.Provider>
)
}
// TimelineContent
function TimelineContent({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
data-slot="timeline-content"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}
// TimelineDate
interface TimelineDateProps extends React.HTMLAttributes<HTMLTimeElement> {
asChild?: boolean
}
function TimelineDate({
asChild = false,
className,
...props
}: TimelineDateProps) {
const Comp = asChild ? Slot.Root : "time"
return (
<Comp
data-slot="timeline-date"
className={cn(
"text-muted-foreground mb-1 block text-xs font-medium group-data-[orientation=vertical]/timeline:max-sm:h-4",
className
)}
{...props}
/>
)
}
// TimelineHeader
function TimelineHeader({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div data-slot="timeline-header" className={cn(className)} {...props} />
)
}
// TimelineIndicator
interface TimelineIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {
asChild?: boolean
}
function TimelineIndicator({
asChild = false,
className,
children,
...props
}: TimelineIndicatorProps) {
return (
<div
data-slot="timeline-indicator"
className={cn(
"border-primary/20 group-data-completed/timeline-item:border-primary absolute size-4 rounded-full border-2 group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:left-0 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:top-0 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2",
className
)}
aria-hidden="true"
{...props}
>
{children}
</div>
)
}
// TimelineItem
interface TimelineItemProps extends React.HTMLAttributes<HTMLDivElement> {
step: number
}
function TimelineItem({ step, className, ...props }: TimelineItemProps) {
const { activeStep } = useTimeline()
return (
<div
data-slot="timeline-item"
className={cn(
"group/timeline-item has-[+[data-completed]]:[&_[data-slot=timeline-separator]]:bg-primary relative flex flex-1 flex-col gap-0.5 group-data-[orientation=horizontal]/timeline:mt-8 group-data-[orientation=horizontal]/timeline:not-last:pe-8 group-data-[orientation=vertical]/timeline:ms-8 group-data-[orientation=vertical]/timeline:not-last:pb-12",
className
)}
data-completed={step <= activeStep || undefined}
{...props}
/>
)
}
// TimelineSeparator
function TimelineSeparator({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
data-slot="timeline-separator"
className={cn(
"bg-primary/10 absolute self-start group-last/timeline-item:hidden group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:h-0.5 group-data-[orientation=horizontal]/timeline:w-[calc(100%-1rem-0.25rem)] group-data-[orientation=horizontal]/timeline:translate-x-4.5 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:h-[calc(100%-1rem-0.25rem)] group-data-[orientation=vertical]/timeline:w-0.5 group-data-[orientation=vertical]/timeline:-translate-x-1/2 group-data-[orientation=vertical]/timeline:translate-y-4.5",
className
)}
aria-hidden="true"
{...props}
/>
)
}
// TimelineTitle
function TimelineTitle({
className,
...props
}: React.HTMLAttributes<HTMLHeadingElement>) {
return (
<h3
data-slot="timeline-title"
className={cn("text-sm font-medium", className)}
{...props}
/>
)
}
export {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
}
-6
View File
@@ -1,6 +0,0 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}