2026-05-05 17:59:30 +00:00
|
|
|
import React from 'react'
|
|
|
|
|
import { FaClipboardCheck, FaQuestionCircle, FaUsers, FaClock, FaArrowRight } from 'react-icons/fa'
|
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
import { SurveyDto } from '@/proxy/intranet/models'
|
|
|
|
|
import useLocale from '@/utils/hooks/useLocale'
|
|
|
|
|
import { currentLocalDate } from '@/utils/dateUtils'
|
|
|
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
|
|
|
|
|
|
|
|
interface SurveysProps {
|
|
|
|
|
surveys?: SurveyDto[]
|
|
|
|
|
onTakeSurvey: (survey: SurveyDto) => void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Surveys: React.FC<SurveysProps> = ({ surveys, onTakeSurvey }) => {
|
|
|
|
|
const currentLocale = useLocale()
|
|
|
|
|
const { translate } = useLocalization()
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="bg-gradient-to-br from-white to-gray-50 dark:from-gray-800 dark:to-gray-850 rounded-xl shadow-lg border border-gray-200/50 dark:border-gray-700/50 overflow-hidden">
|
|
|
|
|
{/* Header with gradient */}
|
|
|
|
|
|
|
|
|
|
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
|
|
|
|
|
<h2 className="text-base font-semibold text-gray-900 dark:text-white flex items-center gap-2">
|
|
|
|
|
<FaClipboardCheck className="w-5 h-5" />
|
|
|
|
|
{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.Title')}
|
|
|
|
|
</h2>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-06 13:47:18 +00:00
|
|
|
<div className="p-3 space-y-4">
|
2026-05-05 17:59:30 +00:00
|
|
|
{surveys?.map((survey, index) => {
|
|
|
|
|
const daysLeft = dayjs(survey.deadline).diff(dayjs(), 'day')
|
|
|
|
|
const urgency = daysLeft <= 3 ? 'urgent' : daysLeft <= 7 ? 'warning' : 'normal'
|
2026-05-06 13:47:18 +00:00
|
|
|
const isCompleted = !!survey.myResponse
|
2026-05-05 17:59:30 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
key={survey.id}
|
|
|
|
|
onClick={() => onTakeSurvey(survey)}
|
2026-05-06 13:47:18 +00:00
|
|
|
className={`group relative p-5 rounded-xl border cursor-pointer transition-all duration-300 hover:shadow-lg hover:-translate-y-1 ${
|
|
|
|
|
isCompleted
|
|
|
|
|
? 'bg-green-50 dark:bg-green-900/20 border-green-300 dark:border-green-700 hover:border-green-400 dark:hover:border-green-500'
|
|
|
|
|
: 'bg-white dark:bg-gray-750 border-gray-200 dark:border-gray-600 hover:border-purple-300 dark:hover:border-purple-500'
|
|
|
|
|
}`}
|
2026-05-05 17:59:30 +00:00
|
|
|
>
|
|
|
|
|
{/* Background gradient on hover */}
|
2026-05-06 13:47:18 +00:00
|
|
|
<div className={`absolute inset-0 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300 ${
|
|
|
|
|
isCompleted
|
|
|
|
|
? 'bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-900/10 dark:to-emerald-900/10'
|
|
|
|
|
: 'bg-gradient-to-r from-purple-50 to-pink-50 dark:from-purple-900/10 dark:to-pink-900/10'
|
|
|
|
|
}`}></div>
|
2026-05-05 17:59:30 +00:00
|
|
|
|
|
|
|
|
<div className="relative">
|
|
|
|
|
{/* Survey Title */}
|
|
|
|
|
<div className="flex items-start justify-between mb-3">
|
2026-05-06 13:47:18 +00:00
|
|
|
<div className="flex items-center gap-2 flex-1 min-w-0">
|
|
|
|
|
{isCompleted && (
|
|
|
|
|
<span className="flex-shrink-0 inline-flex items-center justify-center w-5 h-5 bg-green-500 rounded-full">
|
|
|
|
|
<svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
|
|
|
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
<h4 className={`text-base font-semibold transition-colors ${
|
|
|
|
|
isCompleted
|
|
|
|
|
? 'text-green-800 dark:text-green-300 group-hover:text-green-700 dark:group-hover:text-green-200'
|
|
|
|
|
: 'text-gray-900 dark:text-white group-hover:text-purple-700 dark:group-hover:text-purple-300'
|
|
|
|
|
}`}>
|
|
|
|
|
{survey.title}
|
|
|
|
|
</h4>
|
|
|
|
|
</div>
|
2026-05-05 17:59:30 +00:00
|
|
|
<div
|
|
|
|
|
className={`px-2 py-1 text-center rounded-full text-xs font-medium ${
|
|
|
|
|
urgency === 'urgent'
|
|
|
|
|
? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300'
|
|
|
|
|
: urgency === 'warning'
|
|
|
|
|
? 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300'
|
|
|
|
|
: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
{daysLeft > 0 ? translate('::App.Platform.Intranet.Widgets.ActiveSurveys.DaysLeft', { count: daysLeft }) : translate('::App.Platform.Intranet.Widgets.ActiveSurveys.LastDay')}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Survey Stats */}
|
|
|
|
|
<div className="grid grid-cols-3 gap-4 mb-4">
|
|
|
|
|
<div className="flex items-center gap-2 text-sm">
|
|
|
|
|
<div className="p-1.5 bg-blue-100 dark:bg-blue-900/30 rounded-lg">
|
|
|
|
|
<FaQuestionCircle className="w-3 h-3 text-blue-600 dark:text-blue-400" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="text-xs text-gray-500 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.Questions')}</p>
|
|
|
|
|
<p className="font-semibold text-gray-900 dark:text-white">
|
|
|
|
|
{survey.questions.length}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-2 text-sm">
|
|
|
|
|
<div className="p-1.5 bg-green-100 dark:bg-green-900/30 rounded-lg">
|
|
|
|
|
<FaUsers className="w-3 h-3 text-green-600 dark:text-green-400" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="text-xs text-gray-500 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.Responses')}</p>
|
|
|
|
|
<p className="font-semibold text-gray-900 dark:text-white">
|
|
|
|
|
{survey.responses}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-2 text-sm">
|
|
|
|
|
<div className="p-1.5 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
|
|
|
|
|
<FaClock className="w-3 h-3 text-purple-600 dark:text-purple-400" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="text-xs text-gray-500 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.Duration')}</p>
|
|
|
|
|
<p className="font-semibold text-gray-900 dark:text-white">~5dk</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Progress Bar */}
|
|
|
|
|
<div className="mb-4">
|
|
|
|
|
<div className="flex justify-between text-xs mb-1">
|
|
|
|
|
<span className="text-gray-600 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.CompletionRate')}</span>
|
|
|
|
|
<span className="text-gray-800 dark:text-gray-200 font-medium">
|
|
|
|
|
{Math.round((survey.responses / 100) * 100)}%
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="w-full bg-gray-200 dark:bg-gray-600 rounded-full h-2">
|
|
|
|
|
<div
|
|
|
|
|
className="bg-gradient-to-r from-purple-500 to-pink-500 h-2 rounded-full transition-all duration-500"
|
|
|
|
|
style={{ width: `${Math.min((survey.responses / 100) * 100, 100)}%` }}
|
|
|
|
|
></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Deadline */}
|
|
|
|
|
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
|
|
|
|
<FaClock className="inline w-3 h-3 mr-1" />
|
|
|
|
|
{currentLocalDate(survey.deadline, currentLocale || 'tr')}
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
{/* Action Button */}
|
2026-05-06 13:47:18 +00:00
|
|
|
<button className={`w-full flex items-center justify-center gap-2 px-4 py-3 text-white text-sm font-medium rounded-lg transition-all duration-300 transform group-hover:scale-[1.02] shadow-sm hover:shadow-md ${
|
|
|
|
|
isCompleted
|
|
|
|
|
? 'bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600'
|
|
|
|
|
: 'bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700'
|
|
|
|
|
}`}>
|
|
|
|
|
{isCompleted
|
|
|
|
|
? translate('::App.Platform.Intranet.Widgets.ActiveSurveys.ViewResponses')
|
|
|
|
|
: translate('::App.Platform.Intranet.Widgets.ActiveSurveys.FillSurvey')}
|
2026-05-05 17:59:30 +00:00
|
|
|
<FaArrowRight className="w-3 h-3 transition-transform group-hover:translate-x-1" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
|
|
{surveys?.length === 0 && (
|
|
|
|
|
<div className="text-center py-12">
|
|
|
|
|
<div className="inline-flex items-center justify-center w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full mb-4">
|
|
|
|
|
<FaClipboardCheck className="w-8 h-8 text-gray-400" />
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
|
|
|
|
|
{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.NoActive')}
|
|
|
|
|
</h3>
|
|
|
|
|
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
|
|
|
{translate('::App.Platform.Intranet.Widgets.ActiveSurveys.WillAppearHere')}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default Surveys
|