Skip to content

Commit 07ae42a

Browse files
committed
refactor: apps and timelie
1 parent ca2ebdf commit 07ae42a

File tree

7 files changed

+422
-586
lines changed

7 files changed

+422
-586
lines changed

src/components/AppCard.js

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,62 @@
11
import React from 'react';
22
import { Link } from 'react-router-dom';
3-
import { ArrowRight } from '@phosphor-icons/react';
3+
import { ArrowRight, Star } from '@phosphor-icons/react';
4+
import { motion } from 'framer-motion';
5+
import GenerativeArt from './GenerativeArt';
46
import { appIcons } from '../utils/appIcons';
57

68
const AppCard = ({ app }) => {
7-
const { to, title, description } = app;
8-
const Icon = appIcons[app.icon];
9+
const { to, title, description, icon, pinned_order } = app;
10+
const Icon = appIcons[icon];
911

1012
return (
11-
<Link to={to} className="block h-full group">
12-
<div className="relative h-full p-6 bg-gray-800/40 border border-gray-700 rounded-2xl overflow-hidden transition-all duration-300 hover:-translate-y-1 hover:shadow-xl hover:border-primary-500/50 flex flex-col">
13-
{/* Gradient Glow Effect */}
14-
<div className="absolute inset-0 opacity-0 group-hover:opacity-20 transition-opacity duration-500 bg-gradient-to-br from-primary-500 to-transparent pointer-events-none" />
15-
16-
<div className="relative z-10 flex flex-col h-full">
17-
<div className="flex items-center gap-4 mb-4">
18-
<div className="p-3 rounded-xl bg-gray-700/50 text-primary-400 group-hover:text-white group-hover:bg-primary-500 transition-colors duration-300">
19-
{Icon && <Icon size={32} weight="duotone" />}
20-
</div>
21-
<h3 className="text-xl font-semilight font-mono text-gray-100 group-hover:text-white transition-colors">
22-
{title}
23-
</h3>
13+
<motion.div
14+
whileHover={{ y: -5 }}
15+
className="group relative flex flex-col overflow-hidden rounded-sm bg-zinc-900 border border-white/10 h-full"
16+
>
17+
<Link to={to} className="flex flex-col h-full">
18+
{/* Visual Header */}
19+
<div className="relative h-32 w-full overflow-hidden border-b border-white/5">
20+
<GenerativeArt
21+
seed={title + (icon || 'app')}
22+
className="w-full h-full opacity-40 transition-transform duration-700 ease-out group-hover:scale-110"
23+
/>
24+
<div className="absolute inset-0 bg-gradient-to-t from-zinc-900 to-transparent" />
25+
26+
{/* Icon Overlay */}
27+
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
28+
<div className="p-3 rounded-full bg-black/40 backdrop-blur-md border border-white/10 text-emerald-400 transform group-hover:scale-110 transition-transform duration-500">
29+
{Icon && <Icon size={32} weight="duotone" />}
30+
</div>
2431
</div>
25-
<p className="text-gray-400 text-sm leading-relaxed flex-grow font-sans">
32+
33+
{/* Pinned Badge */}
34+
{pinned_order && (
35+
<div className="absolute top-3 right-3 text-yellow-400 drop-shadow-md">
36+
<Star weight="fill" size={18} />
37+
</div>
38+
)}
39+
</div>
40+
41+
{/* Content */}
42+
<div className="flex flex-col flex-grow p-5">
43+
<h3 className="text-lg font-medium font-sans uppercase text-white mb-3 group-hover:text-emerald-400 transition-colors line-clamp-1 leading-tight tracking-tight">
44+
{title}
45+
</h3>
46+
47+
<p className="text-xs text-gray-400 line-clamp-2 leading-relaxed mb-4 flex-grow font-sans">
2648
{description}
2749
</p>
2850

29-
<div className="mt-6 flex items-center text-sm font-medium text-primary-400 group-hover:text-primary-300 transition-colors font-mono">
30-
Launch App{' '}
31-
<ArrowRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-1" />
51+
<div className="mt-auto pt-4 flex items-center justify-between border-t border-white/5">
52+
<span className="text-[10px] font-mono font-bold uppercase tracking-widest text-gray-500 group-hover:text-white transition-colors">
53+
Open App
54+
</span>
55+
<ArrowRight weight="bold" size={14} className="text-emerald-500 transform -translate-x-2 opacity-0 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100" />
3256
</div>
3357
</div>
34-
</div>
35-
</Link>
58+
</Link>
59+
</motion.div>
3660
);
3761
};
3862

src/components/CustomDropdown.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ const CustomDropdown = ({
1010
icon: Icon,
1111
label,
1212
className = '',
13+
variant = 'default',
1314
}) => {
1415
const [isOpen, setIsOpen] = useState(false);
1516
const dropdownRef = useRef(null); // Ref for the button
1617
const menuRef = useRef(null); // Ref for the dropdown menu
1718
const [dropdownMenuPosition, setDropdownMenuPosition] = useState({});
1819

20+
const isBrutalist = variant === 'brutalist';
21+
1922
useEffect(() => {
2023
const handleClickOutside = (event) => {
2124
const isClickInsideButton =
@@ -63,7 +66,11 @@ const CustomDropdown = ({
6366
animate={{ opacity: 1, y: 0, scale: 1 }}
6467
exit={{ opacity: 0, y: -10, scale: 0.95 }}
6568
transition={{ duration: 0.1 }}
66-
className="bg-gray-800 border border-gray-700 rounded-md shadow-lg z-50 origin-top-left max-h-80 overflow-y-auto" // Added max-h-80 and overflow-y-auto
69+
className={`${
70+
isBrutalist
71+
? "bg-[#050505] border border-white/10 rounded-sm"
72+
: "bg-gray-800 border border-gray-700 rounded-md shadow-lg"
73+
} z-[1000] origin-top-left max-h-80 overflow-y-auto`}
6774
style={{
6875
position: 'absolute',
6976
top: dropdownMenuPosition.top,
@@ -72,20 +79,28 @@ const CustomDropdown = ({
7279
width: 'max-content', // Allow content to determine width, but respect minWidth
7380
}}
7481
>
75-
<div className="py-1">
82+
<div className={isBrutalist ? "p-1" : "py-1"}>
7683
{options.map((option) => (
7784
<button
7885
key={option.value}
7986
onClick={() => handleSelect(option.value)}
80-
className={`flex items-center justify-between w-full px-4 py-2 text-sm text-left transition-colors ${
81-
value === option.value
82-
? 'bg-primary-500/10 text-primary-400'
83-
: 'text-gray-300 hover:bg-gray-700 hover:text-white'
87+
className={`flex items-center justify-between w-full px-4 py-2 text-left transition-colors ${
88+
isBrutalist
89+
? `text-xs font-mono uppercase tracking-widest ${
90+
value === option.value
91+
? 'bg-white/10 text-emerald-400'
92+
: 'text-gray-400 hover:bg-white/5 hover:text-white'
93+
}`
94+
: `text-sm ${
95+
value === option.value
96+
? 'bg-primary-500/10 text-primary-400'
97+
: 'text-gray-300 hover:bg-gray-700 hover:text-white'
98+
}`
8499
}`}
85100
>
86101
<span>{option.label}</span>
87102
{value === option.value && (
88-
<Check size={16} className="text-primary-400" />
103+
<Check size={isBrutalist ? 12 : 16} className={isBrutalist ? "text-emerald-400" : "text-primary-400"} />
89104
)}
90105
</button>
91106
))}
@@ -101,14 +116,18 @@ const CustomDropdown = ({
101116
type="button"
102117
ref={dropdownRef} // Attach ref to the button
103118
onClick={() => setIsOpen(!isOpen)}
104-
className="flex items-center justify-between w-full gap-2 px-4 py-2 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-md text-sm font-medium text-gray-200 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-primary-500"
119+
className={`flex items-center justify-between w-full gap-2 px-4 py-2 transition-all focus:outline-none ${
120+
isBrutalist
121+
? "bg-transparent border border-gray-800 rounded-sm text-xs font-mono uppercase tracking-widest text-gray-400 hover:border-gray-600 hover:text-white"
122+
: "bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-md text-sm font-medium text-gray-200 focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-primary-500"
123+
}`}
105124
>
106125
<div className="flex items-center gap-2">
107-
{Icon && <Icon size={20} className="text-gray-400" />}
126+
{Icon && <Icon size={isBrutalist ? 16 : 20} className={isBrutalist ? "text-emerald-500" : "text-gray-400"} />}
108127
<span>{selectedOption ? selectedOption.label : label}</span>
109128
</div>
110129
<CaretDown
111-
size={16}
130+
size={isBrutalist ? 12 : 16}
112131
className={`ml-2 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}
113132
/>
114133
</button>

0 commit comments

Comments
 (0)