Skip to content

Commit

Permalink
Merge pull request #16 from indralukmana/indra-profile
Browse files Browse the repository at this point in the history
feat: ✨ add builder page for _indralukmana_
  • Loading branch information
phipsae authored Aug 16, 2024
2 parents 1061ecf + 0892536 commit 79c7fe5
Show file tree
Hide file tree
Showing 10 changed files with 557 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { type IndraIconSkill } from "~~/app/builders/0x80Ad2861Ab5D4EeA61330A4bd7d6969357C463C3/_data/indra-skills";

type CardProps = {
Icon: IndraIconSkill;
name: string;
description: string;
time: string;
};

const CardContent = ({ Icon, description, name, time }: CardProps) => {
return (
<div className="grid grid-rows-[auto_1fr_auto] gap-y-2 rounded-lg relative h-full w-full py-6 px-8 z-10">
<div className="flex items-center text-sm">
<Icon className="h-5 w-5" />
<h3 className="ml-2 text-lg font-semibold">{name}</h3>
</div>
<p className="text-sm">{description}</p>
<div className="flex justify-end">
<span>{time}</span>
</div>
</div>
);
};

export const CardHoverEffect1 = (props: CardProps) => {
return (
<div className="h-full w-full group relative inline-flex items-center justify-center overflow-hidden rounded-md bg-blue-500 font-medium">
<span className="absolute h-full w-full bg-secondary transition-all duration-300 group-hover:h-0 group-hover:w-0"></span>
<CardContent {...props} />
</div>
);
};

export const CardHoverEffect2 = (props: CardProps) => {
return (
<div className="group relative inline-flex h-full w-full items-center justify-center overflow-hidden rounded-md bg-secondary font-medium text-primary-content">
<span className="absolute h-0 w-0 bg-blue-500 transition-all duration-300 group-hover:h-full group-hover:w-full"></span>
<CardContent {...props} />
</div>
);
};

export const CardHoverEffect3 = (props: CardProps) => {
return (
<div className="group relative h-full w-full overflow-hidden overflow-x-hidden rounded-md bg-secondary">
<span className="absolute inset-0 overflow-hidden rounded-md">
<span className="absolute left-0 aspect-square w-full origin-center -translate-x-full rounded-full bg-blue-500 transition-all duration-500 group-hover:-translate-x-0 group-hover:scale-150"></span>
</span>
<CardContent {...props} />
</div>
);
};

export const CardHoverEffect4 = (props: CardProps) => {
return (
<div className="group relative z-0 h-full w-full overflow-hidden overflow-x-hidden rounded-md bg-secondary">
<span className="absolute inset-0 overflow-hidden rounded-md">
<span className="absolute left-0 aspect-square w-full origin-center translate-x-full rounded-full bg-blue-500 transition-all duration-500 group-hover:-translate-x-0 group-hover:scale-150"></span>
</span>
<CardContent {...props} />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import Image from "next/image";
import indraPhoto from "../_assets/indra_photo_600.jpg";

const IndraAboutMeSection: React.FC = () => {
return (
<section className="container mx-auto py-8">
<div className="flex flex-col md:flex-row justify-center items-center">
<div className="md:flex-shrink-0">
<Image src={indraPhoto} alt="Indra" className="h-48 w-48 object-cover md:w-48 rounded-full" />
</div>
<div className="p-8 space-y-4">
<h2 className="text-3xl font-bold text-center">About Me</h2>
<p>{`I'm a front-end engineer 🧑‍💻 with full-stack prowess 💪, loving the craft of building useful and delightful products.`}</p>
<p>{`My expertise spans React ecosystem across the stack, with a keen interest in Web3 technologies.`}</p>
<p>{`I'm excited about the Ethereum ecosystem and exploring the transformative potential of blockchain technology.`}</p>
</div>
</div>
</section>
);
};

export default IndraAboutMeSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
CardHoverEffect1,
CardHoverEffect2,
CardHoverEffect3,
CardHoverEffect4,
} from "~~/app/builders/0x80Ad2861Ab5D4EeA61330A4bd7d6969357C463C3/_components/CardHover";
import { indraSkills } from "~~/app/builders/0x80Ad2861Ab5D4EeA61330A4bd7d6969357C463C3/_data/indra-skills";

const IndraSkillsSection = (): React.ReactElement => {
return (
<section>
<h2 className="text-2xl font-semibold mb-2">Skills</h2>
<div className="flex min-h-0 flex-col gap-y-3">
<ul className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
{indraSkills.map((skill, index) => (
<li key={skill.name}>
{index % 4 === 0 ? (
<CardHoverEffect1
Icon={skill.icon}
description={skill.description}
name={skill.name}
time={skill.time}
/>
) : index % 3 === 0 ? (
<CardHoverEffect2
Icon={skill.icon}
description={skill.description}
name={skill.name}
time={skill.time}
/>
) : index % 2 === 0 ? (
<CardHoverEffect3
Icon={skill.icon}
description={skill.description}
name={skill.name}
time={skill.time}
/>
) : (
<CardHoverEffect4
Icon={skill.icon}
description={skill.description}
name={skill.name}
time={skill.time}
/>
)}
</li>
))}
</ul>
</div>
</section>
);
};

export default IndraSkillsSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Link from "next/link";
import {
IndraIconSocials,
indraSocials,
} from "~~/app/builders/0x80Ad2861Ab5D4EeA61330A4bd7d6969357C463C3/_data/indra-socials";

type HoverRevealButtonProps = {
Icon: IndraIconSocials;
label: string;
};

const HoverRevealButton = ({ Icon, label }: HoverRevealButtonProps) => {
return (
<div className="relative h-full w-full overflow-hidden rounded bg-primary px-5 py-2.5 text-primary-content transition-all duration-300 hover:bg-secondary hover:ring-2 hover:ring-secondary hover:ring-offset-2">
<span className="flex items-center gap-2">
<Icon className="h-5 w-5" />
{label}
</span>
</div>
);
};

const IndraSocialsSection = () => {
return (
<section>
<h2 className="text-2xl font-semibold mb-2 sr-only">Socials</h2>
<ul className="grid grid-cols-1 md:grid-cols-[repeat(3,1fr)] xl:grid-cols-[repeat(6,1fr)] gap-6 items-center">
{indraSocials.map(social => (
<li key={social.name}>
<Link
aria-label={social.name}
className="flex items-center gap-2 opacity-85 hover:opacity-100 "
href={social.url}
rel="noopener noreferrer"
target="_blank"
>
<HoverRevealButton Icon={social.icon} label={social.username} />
</Link>
</li>
))}
</ul>
</section>
);
};

export default IndraSocialsSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"use client";

import React, { CSSProperties, useEffect, useState } from "react";

interface Sparkle {
id: string;
x: string;
y: string;
color: string;
delay: number;
scale: number;
lifespan: number;
}

interface SparklesTextProps {
className?: string;
text: string;
sparklesCount?: number;
colors?: {
first: string;
second: string;
};
}

const SparklesText: React.FC<SparklesTextProps> = ({
text,
colors = { first: "#9E7AFF", second: "#FE8BBB" },
className = "",
sparklesCount = 10,
}) => {
const [sparkles, setSparkles] = useState<Sparkle[]>([]);

useEffect(() => {
const generateStar = (): Sparkle => ({
id: `${Math.random()}-${Date.now()}`,
x: `${Math.random() * 100}%`,
y: `${Math.random() * 100}%`,
color: Math.random() > 0.5 ? colors.first : colors.second,
delay: Math.random() * 2,
scale: Math.random() * 1 + 0.3,
lifespan: Math.random() * 10 + 5,
});

const initializeStars = () => {
setSparkles(Array.from({ length: sparklesCount }, generateStar));
};

const updateStars = () => {
setSparkles(currentSparkles =>
currentSparkles.map(star => (star.lifespan <= 0 ? generateStar() : { ...star, lifespan: star.lifespan - 0.1 })),
);
};

initializeStars();
const interval = setInterval(updateStars, 100);

return () => clearInterval(interval);
}, [colors.first, colors.second, sparklesCount]);

return (
<div
className={`relative ${className}`}
style={
{
"--sparkles-first-color": colors.first,
"--sparkles-second-color": colors.second,
} as CSSProperties
}
>
{sparkles.map(sparkle => (
<Sparkle key={sparkle.id} {...sparkle} />
))}
<strong className="relative z-10">{text}</strong>
</div>
);
};

const Sparkle: React.FC<Sparkle> = ({ id, x, y, color, delay, scale }) => {
return (
<svg
key={id}
className="absolute pointer-events-none animate-sparkle"
style={{
left: x,
top: y,
fill: color,
animationDelay: `${delay}s`,
transform: `scale(${scale})`,
}}
width="21"
height="21"
viewBox="0 0 21 21"
>
<path d="M9.82531 0.843845C10.0553 0.215178 10.9446 0.215178 11.1746 0.843845L11.8618 2.72026C12.4006 4.19229 12.3916 6.39157 13.5 7.5C14.6084 8.60843 16.8077 8.59935 18.2797 9.13822L20.1561 9.82534C20.7858 10.0553 20.7858 10.9447 20.1561 11.1747L18.2797 11.8618C16.8077 12.4007 14.6084 12.3916 13.5 13.5C12.3916 14.6084 12.4006 16.8077 11.8618 18.2798L11.1746 20.1562C10.9446 20.7858 10.0553 20.7858 9.82531 20.1562L9.13819 18.2798C8.59932 16.8077 8.60843 14.6084 7.5 13.5C6.39157 12.3916 4.19225 12.4007 2.72023 11.8618L0.843814 11.1747C0.215148 10.9447 0.215148 10.0553 0.843814 9.82534L2.72023 9.13822C4.19225 8.59935 6.39157 8.60843 7.5 7.5C8.60843 6.39157 8.59932 4.19229 9.13819 2.72026L9.82531 0.843845Z" />
</svg>
);
};

const IndraSparkleName: React.FC = () => {
return (
<>
<SparklesText text="Indra Lukmana" className="text-4xl font-bold" />
</>
);
};

export default IndraSparkleName;
Loading

0 comments on commit 79c7fe5

Please sign in to comment.