Skip to content

Commit

Permalink
add reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
hussaino03 committed Jan 3, 2025
1 parent cabc67f commit b54ddbf
Show file tree
Hide file tree
Showing 10 changed files with 3,017 additions and 2,745 deletions.
6 changes: 3 additions & 3 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"./{server,client}/**": "npm run format:fix"
}
{
"./{server,client}/**": "npm run format:fix"
}
2 changes: 1 addition & 1 deletion client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import StreakManager from './services/streak/StreakManager';
import ViewManager from './services/view/ViewManager';
import BadgeManager from './services/badge/BadgeManager';
import CollaborationManager from './services/collaboration/CollaborationManager';
import SupportReminder from './components/Modal Management/SupportReminder';
import SupportReminder from './components/Layout/SupportReminder';

const AppContent = () => {
const [isDark, setIsDark] = useState(false);
Expand Down
94 changes: 92 additions & 2 deletions client/src/components/Landing/Landing.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import {
Sparkles,
ChartLine,
Flag,
Users
Users,
Star
} from 'lucide-react';
import Footer from '../Layout/Footer';
import ReviewCards from './ReviewCards';
import { reviews } from './ReviewCards';

const ThemeToggle = ({ isDark, onToggle }) => (
<button
Expand Down Expand Up @@ -271,7 +273,8 @@ const Landing = ({ isDark, onToggle }) => {
</div>
</div>

<div className="mt-32 text-center opacity-0 animate-[scale_0.4s_ease-out_2.2s_forwards]">
{/* Ready to Level Up section */}
<div className="mt-24 text-center opacity-0 animate-[scale_0.4s_ease-out_2.2s_forwards]">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">
Ready to Level Up?
</h2>
Expand All @@ -287,6 +290,93 @@ const Landing = ({ isDark, onToggle }) => {
</div>
</div>

{/* Mobile Reviews Section */}
<div className="sm:hidden mt-24">
<h2 className="text-3xl font-bold text-center text-gray-900 dark:text-white mb-8 opacity-0 animate-[scale_0.4s_ease-out_0.2s_forwards] px-4">
What Users Say
</h2>

{/* Featured Reviews */}
<div className="px-4 space-y-4 mb-8">
{reviews.slice(0, 3).map((review, index) => (
<div
key={index}
className="opacity-0 animate-[scale_0.4s_ease-out_forwards] bg-white/25 dark:bg-gray-800/25
rounded-lg p-4 shadow-sm"
style={{ animationDelay: `${0.3 + index * 0.1}s` }}
>
<div className="flex items-center gap-3 mb-2">
<div className="w-8 h-8 rounded-full bg-gradient-to-r from-blue-500 to-blue-600 flex items-center justify-center">
<span className="text-white text-sm font-semibold">
{review.name.charAt(0)}
</span>
</div>
<div>
<p className="text-sm font-semibold text-gray-800 dark:text-white">
{review.name}
</p>
<p className="text-xs text-gray-600 dark:text-gray-300">
{review.role}
</p>
</div>
</div>
<div className="flex items-center gap-1 mb-2">
{[...Array(review.rating)].map((_, i) => (
<Star key={i} className="w-3.5 h-3.5 fill-current text-yellow-500" />
))}
</div>
<p className="text-sm text-gray-700 dark:text-gray-200">
{review.content}
</p>
</div>
))}
</div>

{/* More Reviews */}
{reviews.length > 3 && (
<>
<p className="text-sm text-center text-gray-600 dark:text-gray-400 mb-4">
Swipe for more reviews
</p>
<div className="flex overflow-x-auto pb-6 px-4 gap-4 scrollbar-none snap-x snap-mandatory">
{reviews.slice(3).map((review, index) => (
<div
key={index + 3}
className="opacity-0 animate-[scale_0.4s_ease-out_forwards] bg-white/25 dark:bg-gray-800/25
rounded-lg p-4 shadow-sm flex-none w-[85%] snap-center"
style={{ animationDelay: `${0.6 + index * 0.1}s` }}
>
{/* Same review card content */}
<div className="flex items-center gap-3 mb-2">
<div className="w-8 h-8 rounded-full bg-gradient-to-r from-blue-500 to-blue-600 flex items-center justify-center">
<span className="text-white text-sm font-semibold">
{review.name.charAt(0)}
</span>
</div>
<div>
<p className="text-sm font-semibold text-gray-800 dark:text-white">
{review.name}
</p>
<p className="text-xs text-gray-600 dark:text-gray-300">
{review.role}
</p>
</div>
</div>
<div className="flex items-center gap-1 mb-2">
{[...Array(review.rating)].map((_, i) => (
<Star key={i} className="w-3.5 h-3.5 fill-current text-yellow-500" />
))}
</div>
<p className="text-sm text-gray-700 dark:text-gray-200">
{review.content}
</p>
</div>
))}
</div>
</>
)}
</div>

{/* Footer */}
<Footer />
</div>
Expand Down
142 changes: 84 additions & 58 deletions client/src/components/Landing/ReviewCards.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export const reviews = [
delay: 0
},
{
name: "Sarah K.",
name: "Sarah",
role: "Student",
content: "Thank you for this. I have ADHD and normal task managers don't work for me, but turning it into a game is def a great motivating factor for me!",
content: "I have ADHD, and normal task managers don't work for me, but gamifying them definitely helps!",
rating: 5,
position: { right: '12%', top: '35%' },
scale: 1,
Expand All @@ -23,7 +23,7 @@ export const reviews = [
{
name: "Liam",
role: "Project Lead",
content: "This is exactly what I needed! I'm building an intranet for a new business, and this tool perfectly fits my needs. The timing couldn’t have been better!",
content: "This is exactly what I needed! This tool perfectly fits my needs.",
rating: 5,
position: { left: '15%', top: '60%' },
scale: 0.9,
Expand All @@ -32,11 +32,35 @@ export const reviews = [
{
name: "Luteyla",
role: "Student",
content: "Much needed app! Love the gamification aspect",
content: "Much needed app! Love the gamification aspect 🎮",
rating: 5,
position: { right: '8%', top: '70%' },
scale: 0.85,
delay: 1.5
},
{
name: "Anwar M.",
role: "Developer",
content: "Great app! I like the UI and the gamification aspect, definitely adding this to my current workflow",
rating: 5,
scale: 0.9,
delay: 2.5
},
{
name: "Usman",
role: "Student",
content: "The project collaboration feature is a nice addition!",
rating: 4,
scale: 0.95,
delay: 1.8
},
{
name: "David",
role: "Designer",
content: "Clean interface, smart features. Makes task & project management actually fun!",
rating: 4,
scale: 0.88,
delay: 0.5
}
];

Expand All @@ -57,81 +81,83 @@ const ReviewCards = () => {
}, []);

const getPosition = (index) => {
if (windowWidth <= 640) { // Mobile
switch(index) {
case 0: return { left: '5%', top: '15%' };
case 1: return { right: '5%', top: '45%' };
default: return null;
}
} else if (windowWidth <= 1024) { // Tablet
switch(index) {
case 0: return { left: '5%', top: '20%' };
case 1: return { right: '5%', top: '30%' };
case 2: return { left: '8%', top: '55%' };
default: return null;
}
} else { // Desktop
return [
{ left: '8%', top: '25%' },
{ right: '12%', top: '35%' },
{ left: '15%', top: '60%' },
{ right: '8%', top: '70%' }
][index];
}
// Only return desktop positions since mobile uses dedicated section
return [
{ left: '8%', top: '25%' },
{ right: '10%', top: '20%' },
{ left: '15%', top: '50%' },
{ right: '6%', top: '65%' },
{ left: '5%', top: '80%' },
{ right: '12%', top: '40%' },
{ left: '20%', top: '35%' }
][index];
};

return (
<div className="pointer-events-none fixed inset-0 z-0 overflow-hidden">
<div className="pointer-events-none fixed inset-0 z-0 overflow-hidden hidden sm:block">
{reviews.map((review, index) => {
const position = getPosition(index);
if (!position) return null;

const baseOpacity = 0.55;
const scrollFactor = Math.max(0, 1 - (scrollY * 0.0015));
const finalOpacity = baseOpacity * scrollFactor;

return (
<div
key={index}
className="fixed transition-all duration-500"
className="fixed transition-all duration-700"
style={{
...position,
width: windowWidth <= 640 ? '200px' : '256px',
opacity: Math.max(0, 0.6 - (scrollY * 0.001)),
transform: `scale(${windowWidth <= 640 ? review.scale * 0.8 : review.scale})`,
width: windowWidth <= 640 ? '180px' : '220px',
transform: `scale(${windowWidth <= 640 ? review.scale * 0.7 : review.scale * 0.85})`,
}}
>
<div
className={`bg-white/20 dark:bg-gray-800/20 backdrop-blur-sm
rounded-lg p-4 shadow-lg animate-float
hover:opacity-80 transition-opacity duration-300`}
className="opacity-0 animate-fadeIn"
style={{
animationDelay: `${review.delay}s`,
animationDuration: '8s'
animationDelay: `${0.5 + index * 0.1}s`,
animationDuration: '0.6s',
animationFillMode: 'forwards'
}}
>
<div className="flex items-center gap-2 mb-2">
<div className="w-8 h-8 rounded-full bg-gradient-to-r from-blue-500 to-blue-600 flex items-center justify-center">
<span className="text-white text-sm font-bold">
{review.name.charAt(0)}
</span>
</div>
<div>
<p className="text-sm font-semibold text-gray-800 dark:text-white">
{review.name}
</p>
<p className="text-xs text-gray-600 dark:text-gray-400">
{review.role}
<div
className="animate-float"
style={{
opacity: finalOpacity,
transition: 'opacity 0.3s ease-out',
animationDelay: `${1 + index * 0.2}s`, // Start floating after fade-in
}}
>
<div className="bg-white/20 dark:bg-gray-800/20 rounded-lg p-3 shadow-sm transition-all duration-300 hover:opacity-100">
<div className="flex items-center gap-2 mb-2">
<div className="w-6 h-6 rounded-full bg-gradient-to-r from-blue-500 to-blue-600 flex items-center justify-center">
<span className="text-white text-xs font-semibold">
{review.name.charAt(0)}
</span>
</div>
<div>
<p className="text-xs font-semibold text-gray-800 dark:text-white">
{review.name}
</p>
<p className="text-[10px] text-gray-600 dark:text-gray-300">
{review.role}
</p>
</div>
</div>
<div className="flex items-center gap-1 mb-1.5">
{[...Array(review.rating)].map((_, i) => (
<Star
key={i}
className="w-2.5 h-2.5 fill-current text-yellow-500"
/>
))}
</div>
<p className="text-xs text-gray-700 dark:text-gray-200 line-clamp-3 font-medium">
{review.content}
</p>
</div>
</div>
<div className="flex items-center gap-1 mb-2">
{[...Array(review.rating)].map((_, i) => (
<Star
key={i}
className="w-3 h-3 fill-current text-yellow-400"
/>
))}
</div>
<p className="text-sm text-gray-700 dark:text-gray-300">
{review.content}
</p>
</div>
</div>
);
Expand Down
Loading

0 comments on commit b54ddbf

Please sign in to comment.