project-standalo-todo-super/app/components/TaskCard.tsx

99 lines
4.9 KiB
TypeScript

"use client";
import { useState } from "react";
interface TaskCardProps {
task: {
id: string;
name: string;
description: string;
points: number;
type: "daily" | "quiz" | "survey" | "referral" | "learning";
completed?: boolean;
};
onComplete: (taskId: string) => void;
}
const taskIcons = {
daily: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clipRule="evenodd" />
</svg>
),
quiz: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path d="M9 4.804A7.968 7.968 0 005.5 4c-1.255 0-2.443.29-3.5.804v10A7.969 7.969 0 015.5 14c1.669 0 3.218.51 4.5 1.385A7.962 7.962 0 0114.5 14c1.255 0 2.443.29 3.5.804v-10A7.968 7.968 0 0014.5 4c-1.255 0-2.443.29-3.5.804V12a1 1 0 11-2 0V4.804z" />
</svg>
),
survey: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" />
<path fillRule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clipRule="evenodd" />
</svg>
),
referral: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path d="M9 6a3 3 0 11-6 0 3 3 0 016 0zM17 6a3 3 0 11-6 0 3 3 0 016 0zM12.93 17c.046-.327.07-.66.07-1a6.97 6.97 0 00-1.5-4.33A5 5 0 0119 16v1h-6.07zM6 11a5 5 0 015 5v1H1v-1a5 5 0 015-5z" />
</svg>
),
learning: (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z" />
</svg>
),
};
const typeColors = {
daily: "from-blue-500 to-cyan-500",
quiz: "from-purple-500 to-pink-500",
survey: "from-green-500 to-teal-500",
referral: "from-orange-500 to-red-500",
learning: "from-indigo-500 to-purple-500",
};
export default function TaskCard({ task, onComplete }: TaskCardProps) {
const [loading, setLoading] = useState(false);
const handleComplete = async () => {
setLoading(true);
await onComplete(task.id);
setLoading(false);
};
return (
<div className="bg-gray-800 border border-gray-700 rounded-xl p-6 hover:border-gray-600 transition group">
<div className="flex items-start justify-between mb-4">
<div className={`p-3 rounded-lg bg-gradient-to-br ${typeColors[task.type]} text-white shadow-lg group-hover:scale-110 transition`}>
{taskIcons[task.type]}
</div>
<div className="flex items-center gap-2 bg-yellow-500/20 border border-yellow-500/30 rounded-full px-3 py-1">
<svg className="w-4 h-4 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg>
<span className="text-yellow-400 font-bold">{task.points}</span>
</div>
</div>
<h3 className="text-xl font-semibold text-white mb-2">{task.name}</h3>
<p className="text-gray-400 text-sm mb-4 line-clamp-2">{task.description}</p>
{task.completed ? (
<div className="flex items-center justify-center gap-2 bg-green-500/20 border border-green-500 rounded-lg py-2 text-green-400">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
<span className="font-medium">Completed</span>
</div>
) : (
<button
onClick={handleComplete}
disabled={loading}
className="w-full bg-gradient-to-r from-yellow-500 to-orange-500 text-white font-semibold py-2 rounded-lg hover:from-yellow-600 hover:to-orange-600 transition transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none"
>
{loading ? "Processing..." : "Start Task"}
</button>
)}
</div>
);
}