← back to kwaheedkotb__addci-prototype

Function bodies 182 total

All specs Real LLM only Function bodies
TimeSeriesStatic function · typescript · L23-L113 (91 LOC)
components/kpi/TimeSeriesStatic.tsx
export function TimeSeriesStatic({ data }: TimeSeriesStaticProps) {
  const { t, dir } = useI18n()
  const { resolvedTheme } = useTheme()
  const isDark = resolvedTheme === 'dark'

  const gridColor = isDark ? '#334155' : '#e2e8f0'
  const textColor = isDark ? '#94a3b8' : '#64748b'
  const tooltipBg = isDark ? '#1e293b' : '#ffffff'
  const tooltipBorder = isDark ? '#334155' : '#e2e8f0'

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-6" dir={dir}>
      {/* Application Trend Chart */}
      <div className="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-sm border border-slate-200 dark:border-slate-700 transition-colors">
        <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-4">
          {t.kpiDashboard?.applicationTrend || 'Application Trend'}
        </h3>
        <div className="h-[300px]">
          <ResponsiveContainer width="100%" height="100%">
            <BarChart data={data.applicationTrend} margin={{ top: 5, right: 30, left: 20, b
MetricCard function · typescript · L19-L50 (32 LOC)
components/kpi/TopMetricsStatic.tsx
function MetricCard({ title, value, subtitle, icon, trend, trendUp }: MetricCardProps) {
  return (
    <div className="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-sm border border-slate-200 dark:border-slate-700 transition-colors">
      <div className="flex items-start justify-between">
        <div className="flex-1">
          <p className="text-sm font-medium text-slate-500 dark:text-slate-400">{title}</p>
          <p className="mt-2 text-3xl font-bold text-slate-900 dark:text-white">{value}</p>
          {subtitle && (
            <p className="mt-1 text-sm text-slate-500 dark:text-slate-400">{subtitle}</p>
          )}
          {trend && (
            <div className={`mt-2 flex items-center text-sm ${trendUp ? 'text-emerald-600 dark:text-emerald-400' : 'text-red-600 dark:text-red-400'}`}>
              {trendUp ? (
                <svg className="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejo
TopMetricsStatic function · typescript · L52-L151 (100 LOC)
components/kpi/TopMetricsStatic.tsx
export function TopMetricsStatic({ data }: TopMetricsStaticProps) {
  const { t, dir } = useI18n()

  const metrics = [
    {
      title: t.kpiDashboard?.totalApplications || 'Total Applications',
      value: data.totalApplications.toLocaleString(),
      subtitle: `+${data.applicationsThisMonth} ${t.kpiDashboard?.thisMonth || 'this month'}`,
      trend: '+12%',
      trendUp: true,
      icon: (
        <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
        </svg>
      )
    },
    {
      title: t.kpiDashboard?.approvalRate || 'Approval Rate',
      value: `${data.approvalRate}%`,
      trend: '+3.2%',
      trendUp: true,
      icon: (
        <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinec
createSectorIcon function · typescript · L28-L43 (16 LOC)
components/market-directory/MarketMap.tsx
function createSectorIcon(sector: string, isGolden: boolean) {
  const color = sectorHexColors[sector] || '#6b7280'
  return L.divIcon({
    className: 'market-cluster-icon',
    html: `<div style="
      width: 28px; height: 28px; border-radius: 50%;
      background: ${color}; border: 2px solid white;
      box-shadow: 0 2px 6px rgba(0,0,0,0.3);
      display: flex; align-items: center; justify-content: center;
      ${isGolden ? 'box-shadow: 0 0 0 3px #f59e0b, 0 2px 6px rgba(0,0,0,0.3);' : ''}
    "><span style="color:white;font-size:11px;font-weight:bold;">${sector.charAt(0)}</span></div>`,
    iconSize: [28, 28],
    iconAnchor: [14, 14],
    popupAnchor: [0, -16],
  })
}
FlyToCompany function · typescript · L45-L53 (9 LOC)
components/market-directory/MarketMap.tsx
function FlyToCompany({ company }: { company: Company | null }) {
  const map = useMap()
  useEffect(() => {
    if (company) {
      map.flyTo([company.lat, company.lng], 15, { duration: 1.2 })
    }
  }, [company, map])
  return null
}
MarketMap function · typescript · L69-L242 (174 LOC)
components/market-directory/MarketMap.tsx
export default function MarketMap({
  companies,
  areaStats,
  selectedCompany,
  onSelectCompany,
  mapMode,
  isRtl,
}: MarketMapProps) {
  // Compute dominant sector per area for sector clusters mode
  const areaDominantSector = useMemo(() => {
    const map: Record<string, string> = {}
    for (const area of areaStats) {
      if (area.topSectors.length > 0) {
        map[area.area] = area.topSectors[0]
      }
    }
    return map
  }, [areaStats])

  return (
    <div className="relative w-full h-full rounded-xl overflow-hidden" style={{ minHeight: 400 }}>
      <MapContainer
        center={[24.4539, 54.3773]}
        zoom={11}
        scrollWheelZoom={true}
        className="w-full h-full"
        style={{ height: '100%', width: '100%', borderRadius: '0.75rem' }}
      >
        <TileLayer
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />

        <Fl
getStepStatus function · typescript · L7-L21 (15 LOC)
components/ProgressTracker.tsx
function getStepStatus(status: Status, step: number): 'completed' | 'current' | 'upcoming' {
  const statusOrder: Record<Status, number> = {
    SUBMITTED: 1,
    UNDER_REVIEW: 2,
    CORRECTIONS_REQUESTED: 3,
    APPROVED: 4,
    REJECTED: 4,
  }

  const currentStep = statusOrder[status]

  if (step < currentStep) return 'completed'
  if (step === currentStep) return 'current'
  return 'upcoming'
}
Repobility analyzer · published findings · https://repobility.com
ProgressTracker function · typescript · L23-L89 (67 LOC)
components/ProgressTracker.tsx
export default function ProgressTracker({ status }: { status: string }) {
  const { t, dir } = useI18n()
  const typedStatus = status as Status

  const steps = [
    { step: 1, label: t.customer.detail.step1 },
    { step: 2, label: t.customer.detail.step2 },
    { step: 3, label: t.customer.detail.step3 },
    { step: 4, label: typedStatus === 'REJECTED' ? t.status.REJECTED : t.customer.detail.step4 },
  ]

  return (
    <div className="w-full">
      <div className={`flex items-center ${dir === 'rtl' ? 'flex-row-reverse' : ''}`}>
        {steps.map((item, index) => {
          const stepStatus = getStepStatus(typedStatus, item.step)
          const isLast = index === steps.length - 1

          return (
            <div key={item.step} className={`flex items-center ${!isLast ? 'flex-1' : ''}`}>
              <div className="flex flex-col items-center">
                <div
                  className={`w-10 h-10 rounded-full flex items-center justify-center font-semibold text-sm tr
relativeTime function · typescript · L51-L64 (14 LOC)
components/staff/ApplicationDetailPanel.tsx
function relativeTime(dateStr: string, isRtl: boolean): string {
  const now = new Date()
  const date = new Date(dateStr)
  const diffMs = now.getTime() - date.getTime()
  const diffMin = Math.floor(diffMs / 60000)
  const diffHr = Math.floor(diffMin / 60)
  const diffDay = Math.floor(diffHr / 24)

  if (diffMin < 1) return isRtl ? 'الآن' : 'Just now'
  if (diffMin < 60) return isRtl ? `منذ ${diffMin} دقيقة` : `${diffMin}m ago`
  if (diffHr < 24) return isRtl ? `منذ ${diffHr} ساعة` : `${diffHr}h ago`
  if (diffDay < 7) return isRtl ? `منذ ${diffDay} يوم` : `${diffDay}d ago`
  return date.toLocaleDateString(isRtl ? 'ar-AE' : 'en-US', { month: 'short', day: 'numeric' })
}
ApplicationDetailPanel function · typescript · L66-L371 (306 LOC)
components/staff/ApplicationDetailPanel.tsx
export default function ApplicationDetailPanel({
  applicationId,
  serviceType,
  onClose,
  onStatusChange,
  slaDays = null,
  children,
}: ApplicationDetailPanelProps) {
  const { locale, dir } = useI18n()
  const isRtl = locale === 'ar'

  const [application, setApplication] = useState<ApplicationDetail | null>(null)
  const [staffList, setStaffList] = useState<StaffOption[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [newStatus, setNewStatus] = useState('')
  const [newAssignee, setNewAssignee] = useState('')
  const [internalNotes, setInternalNotes] = useState('')
  const [rejectionReason, setRejectionReason] = useState('')
  const [isSaving, setIsSaving] = useState(false)

  const fetchApplication = useCallback(async () => {
    try {
      const res = await fetch(`/api/staff/applications/${applicationId}`)
      const data = await res.json()
      if (data.success) {
        setApplication(data.application)
        setInternalNotes(data.application.internal
ApplicationStatusBadge function · typescript · L29-L42 (14 LOC)
components/staff/ApplicationStatusBadge.tsx
export default function ApplicationStatusBadge({ status }: ApplicationStatusBadgeProps) {
  const { locale } = useI18n()
  const typedStatus = status as ApplicationStatus
  const colors = statusColors[typedStatus] || statusColors.SUBMITTED
  const label = statusLabels[typedStatus]
    ? (locale === 'ar' ? statusLabels[typedStatus].ar : statusLabels[typedStatus].en)
    : status

  return (
    <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${colors}`}>
      {label}
    </span>
  )
}
TableSkeleton function · typescript · L41-L60 (20 LOC)
components/staff/ApplicationTable.tsx
function TableSkeleton() {
  return (
    <div className="rounded-2xl theme-panel overflow-hidden">
      <div className="animate-pulse">
        <div className="h-12" style={{ background: 'var(--panel-2)' }} />
        {Array.from({ length: 5 }).map((_, i) => (
          <div key={i} className="flex items-center gap-4 px-6 py-4" style={{ borderTop: '1px solid var(--border)' }}>
            <div className="w-4 h-4 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-20 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-32 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-16 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-24 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-20 rounded" style={{ background: 'var(--panel-2)' }} />
            <div className="h-4 w-20 rounded" style={{ background: 'var(--panel
ApplicationTable function · typescript · L62-L324 (263 LOC)
components/staff/ApplicationTable.tsx
export default function ApplicationTable({
  applications,
  totalCount,
  page,
  pageSize,
  onPageChange,
  onRowClick,
  onBulkStatusUpdate,
  sortBy,
  sortOrder,
  onSort,
  slaDays = null,
  isLoading = false,
}: ApplicationTableProps) {
  const { locale } = useI18n()
  const isRtl = locale === 'ar'
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [bulkStatus, setBulkStatus] = useState('')

  const totalPages = Math.ceil(totalCount / pageSize)

  const allSelected = useMemo(
    () => applications.length > 0 && applications.every(a => selectedIds.has(a.id)),
    [applications, selectedIds]
  )

  const toggleAll = () => {
    if (allSelected) {
      setSelectedIds(new Set())
    } else {
      setSelectedIds(new Set(applications.map(a => a.id)))
    }
  }

  const toggleOne = (id: string) => {
    setSelectedIds(prev => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }
SLAIndicator function · typescript · L10-L56 (47 LOC)
components/staff/SLAIndicator.tsx
export default function SLAIndicator({ submittedAt, slaDays }: SLAIndicatorProps) {
  const { locale } = useI18n()
  const isRtl = locale === 'ar'

  if (!slaDays || slaDays <= 0) {
    return (
      <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border bg-gray-100 dark:bg-white/10 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-white/10">
        {isRtl ? 'غير محدد' : 'N/A'}
      </span>
    )
  }

  const submitted = new Date(submittedAt)
  const now = new Date()
  const elapsedMs = now.getTime() - submitted.getTime()
  const elapsedDays = elapsedMs / (1000 * 60 * 60 * 24)
  const ratio = elapsedDays / slaDays
  const remaining = slaDays - elapsedDays

  let colorClass: string
  let label: string

  if (ratio > 1) {
    // Breached
    const overdueDays = Math.ceil(elapsedDays - slaDays)
    colorClass = 'bg-red-100 dark:bg-red-500/20 text-red-800 dark:text-red-300 border-red-200 dark:border-red-500/30'
    label = isRtl ? `متأ
StaffAccessGuard function · typescript · L11-L50 (40 LOC)
components/staff/StaffAccessGuard.tsx
export default function StaffAccessGuard({ isAuthorized, children }: StaffAccessGuardProps) {
  const { locale, dir } = useI18n()
  const isRtl = locale === 'ar'

  if (isAuthorized) {
    return <>{children}</>
  }

  return (
    <div className="min-h-screen flex items-center justify-center px-4" style={{ background: 'var(--bg)' }} dir={dir}>
      <div className="max-w-md w-full text-center">
        <div className="w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6" style={{ background: 'var(--accent-red)', opacity: 0.15 }}>
          <svg className="w-10 h-10" style={{ color: 'var(--accent-red)' }} fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
          </svg>
        </div>
        <h2 className="text-2xl font-bold mb-2" style={{ color: 'var(--text)' }}>
          {isRtl ? 
All rows above produced by Repobility · https://repobility.com
StaffFilterBar function · typescript · L25-L125 (101 LOC)
components/staff/StaffFilterBar.tsx
export default function StaffFilterBar({
  searchQuery,
  onSearchChange,
  searchPlaceholder = 'Search applications...',
  searchPlaceholderAr = 'البحث في الطلبات...',
  filters,
  activeFilters,
  onFilterChange,
  onClearAll,
  resultCount,
}: StaffFilterBarProps) {
  const { locale } = useI18n()
  const isRtl = locale === 'ar'

  const hasActiveFilters = searchQuery.length > 0 || Object.values(activeFilters).some(v => v !== '')

  return (
    <div className="mb-6">
      <div className="flex flex-col lg:flex-row gap-4">
        {/* Search */}
        <div className="relative flex-1">
          <svg className={`absolute top-1/2 -translate-y-1/2 w-5 h-5 ${isRtl ? 'right-3' : 'left-3'}`} style={{ color: 'var(--muted)' }} fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
          </svg>
          <input
            type="text"
            value={searc
StatusBadge function · typescript · L16-L29 (14 LOC)
components/StatusBadge.tsx
export default function StatusBadge({ status }: { status: string }) {
  const { t } = useI18n()
  const typedStatus = status as Status

  return (
    <span
      className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
        statusClasses[typedStatus] || 'chip-submitted'
      }`}
    >
      {t.status[typedStatus] || status}
    </span>
  )
}
ThemeProvider function · typescript · L13-L25 (13 LOC)
components/ThemeProvider.tsx
export function ThemeProvider({ children }: { children: ReactNode }) {
  return (
    <NextThemesProvider
      attribute="class"
      defaultTheme="dark"
      enableSystem={true}
      disableTransitionOnChange={false}
      storageKey="esg-portal-theme"
    >
      {children}
    </NextThemesProvider>
  )
}
ThemeToggle function · typescript · L17-L60 (44 LOC)
components/ThemeToggle.tsx
export function ThemeToggle({ className = '' }: ThemeToggleProps) {
  const { theme, setTheme, resolvedTheme } = useTheme()
  const [mounted, setMounted] = useState(false)

  // Prevent hydration mismatch by only rendering after mount
  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setMounted(true)
  }, [])

  if (!mounted) {
    // Return placeholder to prevent layout shift
    return (
      <div className={`w-9 h-9 rounded-lg bg-white/10 ${className}`} />
    )
  }

  const isDark = resolvedTheme === 'dark'

  const toggleTheme = () => {
    setTheme(isDark ? 'light' : 'dark')
  }

  return (
    <button
      onClick={toggleTheme}
      className={`p-2 rounded-lg transition-colors hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/20 ${className}`}
      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
      title={isDark ? 'Light mode' : 'Dark mode'}
    >
      {isDark ? (
        // Sun icon for switchin
logActivity function · typescript · L4-L20 (17 LOC)
lib/activity-log.ts
export async function logActivity(
  applicationId: string,
  serviceType: ServiceType,
  action: string,
  performedBy: string,
  notes?: string
) {
  return prisma.activityLog.create({
    data: {
      applicationId,
      serviceType,
      action,
      performedBy,
      notes: notes ?? null,
    },
  })
}
futureDate function · typescript · L113-L117 (5 LOC)
lib/global-tenders-data.ts
function futureDate(days: number): string {
  const d = new Date()
  d.setDate(d.getDate() + days)
  return d.toISOString().split('T')[0]
}
pastDate function · typescript · L119-L123 (5 LOC)
lib/global-tenders-data.ts
function pastDate(days: number): string {
  const d = new Date()
  d.setDate(d.getDate() - days)
  return d.toISOString().split('T')[0]
}
I18nProvider function · typescript · L21-L52 (32 LOC)
lib/i18n.tsx
export function I18nProvider({ children }: { children: ReactNode }) {
  const [locale, setLocaleState] = useState<Locale>('en')
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    const saved = localStorage.getItem('locale') as Locale | null
    if (saved && (saved === 'en' || saved === 'ar')) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setLocaleState(saved)
    }
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setMounted(true)
  }, [])

  const setLocale = (newLocale: Locale) => {
    setLocaleState(newLocale)
    localStorage.setItem('locale', newLocale)
  }

  const value: I18nContextType = {
    locale,
    setLocale,
    t: translations[locale],
    dir: locale === 'ar' ? 'rtl' : 'ltr',
  }

  if (!mounted) {
    return null
  }

  return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
}
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
useI18n function · typescript · L54-L60 (7 LOC)
lib/i18n.tsx
export function useI18n() {
  const context = useContext(I18nContext)
  if (!context) {
    throw new Error('useI18n must be used within an I18nProvider')
  }
  return context
}
getKPISummary function · typescript · L146-L150 (5 LOC)
lib/kpi-mock-client.ts
export async function getKPISummary(): Promise<KPISummary> {
  // Simulate network delay for realistic feel
  await new Promise(resolve => setTimeout(resolve, 100))
  return kpiSummary as KPISummary
}
getKPITimeSeries function · typescript · L152-L155 (4 LOC)
lib/kpi-mock-client.ts
export async function getKPITimeSeries(): Promise<KPITimeSeries> {
  await new Promise(resolve => setTimeout(resolve, 100))
  return kpiTimeseries as KPITimeSeries
}
getKPIFunnel function · typescript · L157-L160 (4 LOC)
lib/kpi-mock-client.ts
export async function getKPIFunnel(): Promise<KPIFunnel> {
  await new Promise(resolve => setTimeout(resolve, 100))
  return kpiFunnel as KPIFunnel
}
getKPIESG function · typescript · L162-L165 (4 LOC)
lib/kpi-mock-client.ts
export async function getKPIESG(): Promise<KPIESG> {
  await new Promise(resolve => setTimeout(resolve, 100))
  return kpiEsg as KPIESG
}
getKPIAI function · typescript · L167-L170 (4 LOC)
lib/kpi-mock-client.ts
export async function getKPIAI(): Promise<KPIAI> {
  await new Promise(resolve => setTimeout(resolve, 100))
  return kpiAi as KPIAI
}
getRecentApplications function · typescript · L172-L175 (4 LOC)
lib/kpi-mock-client.ts
export async function getRecentApplications(): Promise<RecentApplicationsData> {
  await new Promise(resolve => setTimeout(resolve, 100))
  return recentApplications as RecentApplicationsData
}
getAllKPIData function · typescript · L178-L196 (19 LOC)
lib/kpi-mock-client.ts
export async function getAllKPIData() {
  const [summary, timeseries, funnel, esg, ai, applications] = await Promise.all([
    getKPISummary(),
    getKPITimeSeries(),
    getKPIFunnel(),
    getKPIESG(),
    getKPIAI(),
    getRecentApplications()
  ])

  return {
    summary,
    timeseries,
    funnel,
    esg,
    ai,
    applications
  }
}
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
main function · typescript · L5-L81 (77 LOC)
scripts/clear-applications.ts
async function main() {
  console.log('=== BEFORE CLEAR ===')

  const [
    activityLogs,
    knowledgeSharingApps,
    esgApps,
    baseApps,
    certificates,
    reviewNotes,
    applicationDocs,
    legacyApps,
  ] = await Promise.all([
    prisma.activityLog.count(),
    prisma.knowledgeSharingApplication.count(),
    prisma.esgApplication.count(),
    prisma.baseApplication.count(),
    prisma.certificate.count(),
    prisma.reviewNote.count(),
    prisma.applicationDocument.count(),
    prisma.application.count(),
  ])

  console.log(`  ActivityLog:                  ${activityLogs}`)
  console.log(`  KnowledgeSharingApplication:  ${knowledgeSharingApps}`)
  console.log(`  EsgApplication:               ${esgApps}`)
  console.log(`  BaseApplication:              ${baseApps}`)
  console.log(`  Certificate:                  ${certificates}`)
  console.log(`  ReviewNote:                   ${reviewNotes}`)
  console.log(`  ApplicationDocument:          ${applicationDocs}`)
  console.
‹ prevpage 4 / 4