Intranet dil keylerin düzenlemesi

This commit is contained in:
Sedat ÖZTÜRK 2026-01-27 11:25:39 +03:00
parent b0eafa5018
commit 265d203b95
28 changed files with 1441 additions and 201 deletions

File diff suppressed because it is too large Load diff

View file

@ -121,7 +121,7 @@ function RolesPermission({
setTimeout(async () => { setTimeout(async () => {
getConfig(true) getConfig(true)
}, 6000) }, 3000)
} }
function getPermissionsWithGroupName(groups: PermissionGroupDto[]): PermissionWithGroupName[] { function getPermissionsWithGroupName(groups: PermissionGroupDto[]): PermissionWithGroupName[] {

View file

@ -104,7 +104,7 @@ function UsersPermission({
setTimeout(async () => { setTimeout(async () => {
getConfig(true) getConfig(true)
}, 6000) }, 3000)
} }
function getPermissionsWithGroupName(groups: PermissionGroupDto[]): PermissionWithGroupName[] { function getPermissionsWithGroupName(groups: PermissionGroupDto[]): PermissionWithGroupName[] {

View file

@ -28,7 +28,9 @@ interface CreatePostProps {
}) => void }) => void
} }
import { useLocalization } from '@/utils/hooks/useLocalization'
const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => { const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => {
const { translate } = useLocalization();
const [content, setContent] = useState('') const [content, setContent] = useState('')
const [mediaType, setMediaType] = useState<'media' | 'poll' | null>(null) const [mediaType, setMediaType] = useState<'media' | 'poll' | null>(null)
const [mediaItems, setMediaItems] = useState<SocialMediaDto[]>([]) const [mediaItems, setMediaItems] = useState<SocialMediaDto[]>([])
@ -164,7 +166,7 @@ const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => {
value={content} value={content}
onChange={(e) => setContent(e.target.value)} onChange={(e) => setContent(e.target.value)}
onFocus={() => setIsExpanded(true)} onFocus={() => setIsExpanded(true)}
placeholder="Ne düşünüyorsunuz?" placeholder={translate('::App.Platform.Intranet.SocialWall.CreatePost.Placeholder')}
className={classNames( className={classNames(
'w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none transition-all', 'w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none transition-all',
isExpanded ? 'min-h-[120px]' : 'min-h-[48px]' isExpanded ? 'min-h-[120px]' : 'min-h-[48px]'

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { FaExternalLinkAlt, FaMapMarkerAlt } from 'react-icons/fa' import { FaExternalLinkAlt, FaMapMarkerAlt } from 'react-icons/fa'
interface LocationData { interface LocationData {
@ -43,6 +44,7 @@ const LocationMap: React.FC<LocationMapProps> = ({
return `https://www.openstreetmap.org/export/embed.html?bbox=${lng - 0.01},${lat - 0.01},${lng + 0.01},${lat + 0.01}&layer=mapnik&marker=${lat},${lng}` return `https://www.openstreetmap.org/export/embed.html?bbox=${lng - 0.01},${lat - 0.01},${lng + 0.01},${lat + 0.01}&layer=mapnik&marker=${lat},${lng}`
} }
const { translate } = useLocalization();
return ( return (
<div className={`relative rounded-lg overflow-hidden bg-gray-200 dark:bg-gray-700 ${className}`}> <div className={`relative rounded-lg overflow-hidden bg-gray-200 dark:bg-gray-700 ${className}`}>
{/* Map Container */} {/* Map Container */}
@ -76,9 +78,9 @@ const LocationMap: React.FC<LocationMapProps> = ({
<button <button
onClick={handleOpenGoogleMaps} onClick={handleOpenGoogleMaps}
className="absolute inset-0 w-full h-full cursor-pointer group" className="absolute inset-0 w-full h-full cursor-pointer group"
aria-label="Google Maps'te aç" aria-label={translate('::App.Platform.Intranet.SocialWall.LocationMap.OpenInGoogleMaps')}
> >
<span className="sr-only">Google Maps'te </span> <span className="sr-only">{translate('::App.Platform.Intranet.SocialWall.LocationMap.OpenInGoogleMaps')}</span>
</button> </button>
{/* Hover Effect */} {/* Hover Effect */}
@ -93,10 +95,10 @@ const LocationMap: React.FC<LocationMapProps> = ({
className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors" className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors"
> >
<FaExternalLinkAlt className="w-5 h-5" /> <FaExternalLinkAlt className="w-5 h-5" />
<span>Google Maps'te </span> <span>{translate('::App.Platform.Intranet.SocialWall.LocationMap.OpenInGoogleMaps')}</span>
</button> </button>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-2 text-center"> <p className="text-xs text-gray-500 dark:text-gray-400 mt-2 text-center">
Yol tarifi almak için tıklayın {translate('::App.Platform.Intranet.SocialWall.LocationMap.ClickForDirections')}
</p> </p>
</div> </div>
)} )}

View file

@ -1,4 +1,5 @@
import React, { useState, useEffect, useRef } from 'react' import React, { useState, useEffect, useRef } from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes, FaSearch, FaMapMarkerAlt } from 'react-icons/fa' import { FaTimes, FaSearch, FaMapMarkerAlt } from 'react-icons/fa'
import classNames from 'classnames' import classNames from 'classnames'
@ -28,6 +29,7 @@ declare global {
} }
const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) => { const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) => {
const { translate } = useLocalization();
const [searchQuery, setSearchQuery] = useState('') const [searchQuery, setSearchQuery] = useState('')
const [locations, setLocations] = useState<LocationData[]>([]) const [locations, setLocations] = useState<LocationData[]>([])
const [selectedLocation, setSelectedLocation] = useState<LocationData | null>(null) const [selectedLocation, setSelectedLocation] = useState<LocationData | null>(null)
@ -55,7 +57,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
} }
if (!GOOGLE_API_KEY) { if (!GOOGLE_API_KEY) {
setError('Google Maps API anahtarı bulunamadı. Lütfen .env dosyasına VITE_GOOGLE_MAPS_API_KEY ekleyin.') setError(translate('::App.Platform.Intranet.SocialWall.LocationPicker.ApiKeyError'))
return return
} }
@ -92,7 +94,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
} }
script.onerror = () => { script.onerror = () => {
setError('Google Maps yüklenemedi. Lütfen internet bağlantınızı kontrol edin.') setError(translate('::App.Platform.Intranet.SocialWall.LocationPicker.GoogleMapsLoadError'))
} }
document.head.appendChild(script) document.head.appendChild(script)
@ -142,7 +144,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
} }
if (status !== window.google.maps.places.PlacesServiceStatus.OK) { if (status !== window.google.maps.places.PlacesServiceStatus.OK) {
setError('Konum arama başarısız') setError(translate('::App.Platform.Intranet.SocialWall.LocationPicker.SearchFailed'))
setIsLoading(false) setIsLoading(false)
return return
} }
@ -189,7 +191,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
) )
} catch (err) { } catch (err) {
console.error('Location search error:', err) console.error('Location search error:', err)
setError('Konum arama sırasında bir hata oluştu') setError(translate('::App.Platform.Intranet.SocialWall.LocationPicker.SearchError'))
setIsLoading(false) setIsLoading(false)
} }
}, 500) // 500ms debounce }, 500) // 500ms debounce
@ -222,7 +224,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
> >
{/* Header */} {/* Header */}
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700"> <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Konum Ekle</h2> <h2 className="text-xl font-bold text-gray-900 dark:text-white">{translate('::App.Platform.Intranet.SocialWall.LocationPicker.AddLocation')}</h2>
<button <button
onClick={onClose} onClick={onClose}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors" className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors"
@ -240,14 +242,14 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
type="text" type="text"
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Konum ara..." placeholder={translate('::App.Platform.Intranet.SocialWall.LocationPicker.SearchPlaceholder')}
disabled={!isGoogleLoaded} disabled={!isGoogleLoaded}
className="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-600 disabled:cursor-not-allowed" className="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-600 disabled:cursor-not-allowed"
/> />
</div> </div>
{!isGoogleLoaded && ( {!isGoogleLoaded && (
<p className="text-xs text-gray-500 dark:text-gray-400 mt-2"> <p className="text-xs text-gray-500 dark:text-gray-400 mt-2">
Google Maps yükleniyor... {translate('::App.Platform.Intranet.SocialWall.LocationPicker.LoadingGoogleMaps')}
</p> </p>
)} )}
</div> </div>
@ -257,12 +259,12 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
{!isGoogleLoaded ? ( {!isGoogleLoaded ? (
<div className="text-center py-12"> <div className="text-center py-12">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
<p className="text-gray-500 dark:text-gray-400">Google Maps yükleniyor...</p> <p className="text-gray-500 dark:text-gray-400">{translate('::App.Platform.Intranet.SocialWall.LocationPicker.LoadingGoogleMaps')}</p>
</div> </div>
) : isLoading ? ( ) : isLoading ? (
<div className="text-center py-12"> <div className="text-center py-12">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
<p className="text-gray-500 dark:text-gray-400">Konumlar aranıyor...</p> <p className="text-gray-500 dark:text-gray-400">{translate('::App.Platform.Intranet.SocialWall.LocationPicker.SearchingLocations')}</p>
</div> </div>
) : error ? ( ) : error ? (
<div className="text-center py-12"> <div className="text-center py-12">
@ -273,17 +275,17 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
<div className="text-center py-12"> <div className="text-center py-12">
<FaSearch className="w-16 h-16 mx-auto mb-4 text-gray-400" /> <FaSearch className="w-16 h-16 mx-auto mb-4 text-gray-400" />
<p className="text-gray-500 dark:text-gray-400"> <p className="text-gray-500 dark:text-gray-400">
Aramak istediğiniz konumu yazın {translate('::App.Platform.Intranet.SocialWall.LocationPicker.TypeToSearch')}
</p> </p>
<p className="text-sm text-gray-400 dark:text-gray-500 mt-2"> <p className="text-sm text-gray-400 dark:text-gray-500 mt-2">
Örn: Taksim, İstanbul {translate('::App.Platform.Intranet.SocialWall.LocationPicker.Example')}
</p> </p>
</div> </div>
) : locations.length === 0 ? ( ) : locations.length === 0 ? (
<div className="text-center py-12"> <div className="text-center py-12">
<FaMapMarkerAlt className="w-16 h-16 mx-auto mb-4 text-gray-400" /> <FaMapMarkerAlt className="w-16 h-16 mx-auto mb-4 text-gray-400" />
<p className="text-gray-500 dark:text-gray-400"> <p className="text-gray-500 dark:text-gray-400">
Konum bulunamadı. Farklı bir arama yapın. {translate('::App.Platform.Intranet.SocialWall.LocationPicker.NotFound')}
</p> </p>
</div> </div>
) : ( ) : (
@ -359,7 +361,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
</span> </span>
</span> </span>
) : ( ) : (
<span>Bir konum seçin</span> <span>{translate('::App.Platform.Intranet.SocialWall.LocationPicker.SelectLocation')}</span>
)} )}
</div> </div>
<div className="flex gap-2"> <div className="flex gap-2">
@ -367,14 +369,14 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
onClick={onClose} onClick={onClose}
className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-lg transition-colors" className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-lg transition-colors"
> >
İptal {translate('::App.Platform.Intranet.SocialWall.LocationPicker.Cancel')}
</button> </button>
<button <button
onClick={handleConfirm} onClick={handleConfirm}
disabled={!selectedLocation} disabled={!selectedLocation}
className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors" className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
> >
Ekle {translate('::App.Platform.Intranet.SocialWall.LocationPicker.Add')}
</button> </button>
</div> </div>
</div> </div>

View file

@ -1,4 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes, FaLink, FaUpload } from 'react-icons/fa' import { FaTimes, FaLink, FaUpload } from 'react-icons/fa'
import classNames from 'classnames' import classNames from 'classnames'
@ -11,6 +12,7 @@ interface MediaManagerProps {
} }
const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose }) => { const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose }) => {
const { translate } = useLocalization();
const [activeTab, setActiveTab] = useState<'upload' | 'url'>('upload') const [activeTab, setActiveTab] = useState<'upload' | 'url'>('upload')
const [urlInput, setUrlInput] = useState('') const [urlInput, setUrlInput] = useState('')
const [mediaType, setMediaType] = useState<'image' | 'video'>('image') const [mediaType, setMediaType] = useState<'image' | 'video'>('image')
@ -58,7 +60,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
> >
{/* Header */} {/* Header */}
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700"> <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Medya Ekle</h2> <h2 className="text-xl font-bold text-gray-900 dark:text-white">{translate('::App.Platform.Intranet.SocialWall.MediaManager.AddMedia')}</h2>
<button <button
onClick={onClose} onClick={onClose}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors" className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors"
@ -80,7 +82,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FaUpload className="w-5 h-5" /> <FaUpload className="w-5 h-5" />
<span>Bilgisayarımdan Seç</span> <span>{translate('::App.Platform.Intranet.SocialWall.MediaManager.SelectFromComputer')}</span>
</div> </div>
</button> </button>
<button <button
@ -94,7 +96,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FaLink className="w-5 h-5" /> <FaLink className="w-5 h-5" />
<span>URL ile Ekle</span> <span>{translate('::App.Platform.Intranet.SocialWall.MediaManager.AddByUrl')}</span>
</div> </div>
</button> </button>
</div> </div>
@ -107,10 +109,10 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
<div className="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors cursor-pointer"> <div className="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors cursor-pointer">
<FaUpload className="w-12 h-12 mx-auto mb-4 text-gray-400" /> <FaUpload className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<p className="text-gray-700 dark:text-gray-300 font-medium mb-1"> <p className="text-gray-700 dark:text-gray-300 font-medium mb-1">
Dosya seçmek için tıklayın {translate('::App.Platform.Intranet.SocialWall.MediaManager.ClickToSelectFile')}
</p> </p>
<p className="text-sm text-gray-500 dark:text-gray-400"> <p className="text-sm text-gray-500 dark:text-gray-400">
Resim veya Video (PNG, JPG, GIF, MP4, MOV) {translate('::App.Platform.Intranet.SocialWall.MediaManager.ImageOrVideoFormats')}
</p> </p>
</div> </div>
<input <input
@ -126,7 +128,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
<div> <div>
<div className="mb-4"> <div className="mb-4">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Medya Tipi {translate('::App.Platform.Intranet.SocialWall.MediaManager.MediaType')}
</label> </label>
<div className="flex gap-2"> <div className="flex gap-2">
<button <button
@ -138,7 +140,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
: 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600' : 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
)} )}
> >
Resim {translate('::App.Platform.Intranet.SocialWall.MediaManager.Image')}
</button> </button>
<button <button
onClick={() => setMediaType('video')} onClick={() => setMediaType('video')}
@ -149,7 +151,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
: 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600' : 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
)} )}
> >
Video {translate('::App.Platform.Intranet.SocialWall.MediaManager.Video')}
</button> </button>
</div> </div>
</div> </div>
@ -159,7 +161,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
value={urlInput} value={urlInput}
onChange={(e) => setUrlInput(e.target.value)} onChange={(e) => setUrlInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleUrlAdd()} onKeyPress={(e) => e.key === 'Enter' && handleUrlAdd()}
placeholder={`${mediaType === 'image' ? 'Resim' : 'Video'} URL'si girin`} placeholder={mediaType === 'image' ? translate('::App.Platform.Intranet.SocialWall.MediaManager.EnterImageUrl') : translate('::App.Platform.Intranet.SocialWall.MediaManager.EnterVideoUrl')}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
/> />
<button <button
@ -167,7 +169,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
disabled={!urlInput.trim()} disabled={!urlInput.trim()}
className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors" className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
> >
Ekle {translate('::App.Platform.Intranet.SocialWall.MediaManager.Add')}
</button> </button>
</div> </div>
</div> </div>
@ -177,7 +179,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
{media.length > 0 && ( {media.length > 0 && (
<div className="mt-6"> <div className="mt-6">
<h3 className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3"> <h3 className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">
Eklenen Medyalar ({media.length}) {translate('::App.Platform.Intranet.SocialWall.MediaManager.AddedMedia')} ({media.length})
</h3> </h3>
<div className="grid grid-cols-4 gap-3"> <div className="grid grid-cols-4 gap-3">
{media.map((item) => ( {media.map((item) => (
@ -205,7 +207,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
<FaTimes className="w-4 h-4" /> <FaTimes className="w-4 h-4" />
</button> </button>
<div className="absolute bottom-1 left-1 px-2 py-0.5 bg-black bg-opacity-70 text-white text-xs rounded"> <div className="absolute bottom-1 left-1 px-2 py-0.5 bg-black bg-opacity-70 text-white text-xs rounded">
{item.type === 'image' ? '📷' : '🎥'} {item.type === 'image' ? translate('::App.Platform.Intranet.SocialWall.MediaManager.ImageIcon') : translate('::App.Platform.Intranet.SocialWall.MediaManager.VideoIcon')}
</div> </div>
</div> </div>
))} ))}
@ -220,14 +222,14 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
onClick={onClose} onClick={onClose}
className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
> >
İptal {translate('::App.Platform.Intranet.SocialWall.MediaManager.Cancel')}
</button> </button>
<button <button
onClick={onClose} onClick={onClose}
disabled={media.length === 0} disabled={media.length === 0}
className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors" className="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
> >
Tamam ({media.length}) {translate('::App.Platform.Intranet.SocialWall.MediaManager.Done', { count: media.length })}
</button> </button>
</div> </div>
</motion.div> </motion.div>

View file

@ -1,4 +1,5 @@
import React, { useState, useRef, useEffect } from 'react' import React, { useState, useRef, useEffect } from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion, AnimatePresence } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
import classNames from 'classnames' import classNames from 'classnames'
import dayjs from 'dayjs' import dayjs from 'dayjs'
@ -28,6 +29,7 @@ interface PostItemProps {
} }
const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete, onVote }) => { const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete, onVote }) => {
const { translate } = useLocalization();
const [showComments, setShowComments] = useState(false) const [showComments, setShowComments] = useState(false)
const [commentText, setCommentText] = useState('') const [commentText, setCommentText] = useState('')
const [showAllImages, setShowAllImages] = useState(false) const [showAllImages, setShowAllImages] = useState(false)
@ -269,7 +271,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
id: post.employee.id, id: post.employee.id,
name: post.employee.name, name: post.employee.name,
avatar: post.employee.avatar || 'https://i.pravatar.cc/150?img=1', avatar: post.employee.avatar || 'https://i.pravatar.cc/150?img=1',
title: post.employee.jobPosition?.name || 'Çalışan', title: post.employee.jobPosition?.name || translate('::App.Platform.Intranet.SocialWall.PostItem.Employee'),
email: post.employee.email, email: post.employee.email,
phoneNumber: post.employee.phoneNumber, phoneNumber: post.employee.phoneNumber,
department: post.employee.department?.name, department: post.employee.department?.name,
@ -285,7 +287,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
{post.employee.name} {post.employee.name}
</h3> </h3>
<p className="text-sm text-gray-600 dark:text-gray-400"> <p className="text-sm text-gray-600 dark:text-gray-400">
{post.employee.jobPosition?.name || 'Çalışan'} {dayjs(post.creationTime).fromNow()} {post.employee.jobPosition?.name || translate('::App.Platform.Intranet.SocialWall.PostItem.Employee')} {dayjs(post.creationTime).fromNow()}
</p> </p>
</div> </div>
</div> </div>
@ -293,7 +295,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
<button <button
onClick={() => onDelete(post.id)} onClick={() => onDelete(post.id)}
className="p-2 text-gray-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-full transition-colors" className="p-2 text-gray-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-full transition-colors"
title="Gönderiyi sil" title={translate('::App.Platform.Intranet.SocialWall.PostItem.DeletePost')}
> >
<FaTrash className="w-5 h-5" /> <FaTrash className="w-5 h-5" />
</button> </button>
@ -357,7 +359,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
type="text" type="text"
value={commentText} value={commentText}
onChange={(e) => setCommentText(e.target.value)} onChange={(e) => setCommentText(e.target.value)}
placeholder="Yorum yazın..." placeholder={translate('::App.Platform.Intranet.SocialWall.PostItem.CommentPlaceholder')}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-full bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-full bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
/> />
<button <button
@ -391,7 +393,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
id: comment.creator.id, id: comment.creator.id,
name: comment.creator.name, name: comment.creator.name,
avatar: comment.creator.avatar || 'https://i.pravatar.cc/150?img=1', avatar: comment.creator.avatar || 'https://i.pravatar.cc/150?img=1',
title: comment.creator.jobPosition?.name || 'Çalışan' title: comment.creator.jobPosition?.name || translate('::App.Platform.Intranet.SocialWall.PostItem.Employee')
}} }}
position="bottom" position="bottom"
/> />

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes, FaEye, FaClipboard } from 'react-icons/fa' import { FaTimes, FaEye, FaClipboard } from 'react-icons/fa'
import dayjs from 'dayjs'
import { AnnouncementDto } from '@/proxy/intranet/models' import { AnnouncementDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
@ -12,6 +12,7 @@ interface AnnouncementDetailModalProps {
} }
const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ announcement, onClose }) => { const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ announcement, onClose }) => {
const { translate } = useLocalization();
const currentLocale = useLocale() const currentLocale = useLocale()
const getCategoryColor = (category: string) => { const getCategoryColor = (category: string) => {
const colors: Record<string, string> = { const colors: Record<string, string> = {
@ -49,14 +50,14 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
<span <span
className={`px-3 py-1 text-xs font-medium rounded-full ${getCategoryColor(announcement.category)}`} className={`px-3 py-1 text-xs font-medium rounded-full ${getCategoryColor(announcement.category)}`}
> >
{announcement.category === 'general' && '📢 Genel'} {announcement.category === 'general' && `📢 ${translate('::App.Platform.Intranet.AnnouncementDetailModal.Category.General')}`}
{announcement.category === 'hr' && '👥 İnsan Kaynakları'} {announcement.category === 'hr' && `👥 ${translate('::App.Platform.Intranet.AnnouncementDetailModal.Category.HR')}`}
{announcement.category === 'it' && '💻 Bilgi Teknolojileri'} {announcement.category === 'it' && `💻 ${translate('::App.Platform.Intranet.AnnouncementDetailModal.Category.IT')}`}
{announcement.category === 'event' && '🎉 Etkinlik'} {announcement.category === 'event' && `🎉 ${translate('::App.Platform.Intranet.AnnouncementDetailModal.Category.Event')}`}
{announcement.category === 'urgent' && '🚨 Acil'} {announcement.category === 'urgent' && `🚨 ${translate('::App.Platform.Intranet.AnnouncementDetailModal.Category.Urgent')}`}
</span> </span>
{announcement.isPinned && ( {announcement.isPinned && (
<span className="text-yellow-500 text-sm">📌 Sabitlenmiş</span> <span className="text-yellow-500 text-sm">📌 {translate('::App.Platform.Intranet.AnnouncementDetailModal.Pinned')}</span>
)} )}
</div> </div>
<h2 className="text-2xl font-bold text-gray-900 dark:text-white"> <h2 className="text-2xl font-bold text-gray-900 dark:text-white">
@ -89,7 +90,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
<span></span> <span></span>
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<FaEye className="w-4 h-4" /> <FaEye className="w-4 h-4" />
{announcement.viewCount} görüntülenme {announcement.viewCount} {translate('::App.Platform.Intranet.AnnouncementDetailModal.Views')}
</span> </span>
</div> </div>
</div> </div>
@ -120,7 +121,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
<div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700"> <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
<h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2"> <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2">
<FaClipboard className="w-5 h-5" /> <FaClipboard className="w-5 h-5" />
Ekler ({announcement.attachments.length}) {translate('::App.Platform.Intranet.AnnouncementDetailModal.Attachments')} ({announcement.attachments.length})
</h3> </h3>
<div className="space-y-2"> <div className="space-y-2">
{announcement.attachments.map((attachment, idx) => ( {announcement.attachments.map((attachment, idx) => (
@ -141,7 +142,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
</p> </p>
</div> </div>
<span className="text-sm text-blue-600 dark:text-blue-400"> <span className="text-sm text-blue-600 dark:text-blue-400">
İndir {translate('::App.Platform.Intranet.AnnouncementDetailModal.Download')}
</span> </span>
</a> </a>
))} ))}
@ -154,7 +155,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
announcement.departments.length > 0 && ( announcement.departments.length > 0 && (
<div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700"> <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
<h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3"> <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3">
Hedef Departmanlar {translate('::App.Platform.Intranet.AnnouncementDetailModal.TargetDepartments')}
</h3> </h3>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{announcement.departments?.map((dept, idx) => ( {announcement.departments?.map((dept, idx) => (
@ -173,7 +174,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
{announcement.expiryDate && ( {announcement.expiryDate && (
<div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700"> <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
<p className="text-sm text-gray-600 dark:text-gray-400"> <p className="text-sm text-gray-600 dark:text-gray-400">
<span className="font-medium">Son Geçerlilik Tarihi:</span>{' '} <span className="font-medium">{translate('::App.Platform.Intranet.AnnouncementDetailModal.ExpiryDate')}:</span>{' '}
{currentLocalDate(announcement.expiryDate, currentLocale || 'tr')} {currentLocalDate(announcement.expiryDate, currentLocale || 'tr')}
</p> </p>
</div> </div>
@ -186,7 +187,7 @@ const AnnouncementDetailModal: React.FC<AnnouncementDetailModalProps> = ({ annou
onClick={onClose} onClick={onClose}
className="w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors" className="w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors"
> >
Kapat {translate('::App.Platform.Intranet.AnnouncementDetailModal.Close')}
</button> </button>
</div> </div>
</motion.div> </motion.div>

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes } from 'react-icons/fa' import { FaTimes } from 'react-icons/fa'
@ -8,6 +9,7 @@ interface ExpenseRequestModalProps {
} }
const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSubmit }) => { const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSubmit }) => {
const { translate } = useLocalization();
return ( return (
<> <>
<motion.div <motion.div
@ -27,7 +29,7 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
> >
<div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10"> <div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white"> <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Yeni Harcama Talebi {translate('::App.Platform.Intranet.ExpenseRequestModal.Title')}
</h2> </h2>
<button <button
onClick={onClose} onClick={onClose}
@ -46,29 +48,29 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
> >
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Harcama Kategorisi * {translate('::App.Platform.Intranet.ExpenseRequestModal.Category')}
</label> </label>
<select <select
required required
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
> >
<option value="">Seçiniz</option> <option value="">{translate('::App.Platform.Intranet.ExpenseRequestModal.Select')}</option>
<option value="travel"> Seyahat</option> <option value="travel"> {translate('::App.Platform.Intranet.ExpenseRequestModal.Travel')}</option>
<option value="meal">🍽 Yemek</option> <option value="meal">🍽 {translate('::App.Platform.Intranet.ExpenseRequestModal.Meal')}</option>
<option value="accommodation">🏨 Konaklama</option> <option value="accommodation">🏨 {translate('::App.Platform.Intranet.ExpenseRequestModal.Accommodation')}</option>
<option value="transport">🚗 Ulaşım</option> <option value="transport">🚗 {translate('::App.Platform.Intranet.ExpenseRequestModal.Transport')}</option>
<option value="other">📋 Diğer</option> <option value="other">📋 {translate('::App.Platform.Intranet.ExpenseRequestModal.Other')}</option>
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
ıklama * {translate('::App.Platform.Intranet.ExpenseRequestModal.Description')}
</label> </label>
<input <input
type="text" type="text"
required required
placeholder="Harcama açıklaması..." placeholder={translate('::App.Platform.Intranet.ExpenseRequestModal.DescriptionPlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
@ -76,7 +78,7 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Tutar () * {translate('::App.Platform.Intranet.ExpenseRequestModal.Amount')}
</label> </label>
<input <input
type="number" type="number"
@ -89,7 +91,7 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Tarih * {translate('::App.Platform.Intranet.ExpenseRequestModal.Date')}
</label> </label>
<input <input
type="date" type="date"
@ -101,11 +103,11 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Not {translate('::App.Platform.Intranet.ExpenseRequestModal.Note')}
</label> </label>
<textarea <textarea
rows={3} rows={3}
placeholder="Ek bilgi (opsiyonel)..." placeholder={translate('::App.Platform.Intranet.ExpenseRequestModal.NotePlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
@ -116,13 +118,13 @@ const ExpenseRequestModal: React.FC<ExpenseRequestModalProps> = ({ onClose, onSu
onClick={onClose} onClick={onClose}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
> >
İptal {translate('::App.Platform.Intranet.ExpenseRequestModal.Cancel')}
</button> </button>
<button <button
type="submit" type="submit"
className="flex-1 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors" className="flex-1 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors"
> >
Gönder {translate('::App.Platform.Intranet.ExpenseRequestModal.Submit')}
</button> </button>
</div> </div>
</form> </form>

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes } from 'react-icons/fa' import { FaTimes } from 'react-icons/fa'
@ -8,6 +9,7 @@ interface LeaveRequestModalProps {
} }
const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit }) => { const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit }) => {
const { translate } = useLocalization();
return ( return (
<> <>
<motion.div <motion.div
@ -27,7 +29,7 @@ const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit
> >
<div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10"> <div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white"> <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Yeni İzin Talebi {translate('::App.Platform.Intranet.LeaveRequestModal.Title')}
</h2> </h2>
<button <button
onClick={onClose} onClick={onClose}
@ -46,24 +48,24 @@ const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit
> >
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
İzin Türü * {translate('::App.Platform.Intranet.LeaveRequestModal.LeaveType')}
</label> </label>
<select <select
required required
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
> >
<option value="">Seçiniz</option> <option value="">{translate('::App.Platform.Intranet.LeaveRequestModal.Select')}</option>
<option value="annual">🏖 Yıllık İzin</option> <option value="annual">🏖 {translate('::App.Platform.Intranet.LeaveRequestModal.AnnualLeave')}</option>
<option value="sick">🏥 Hastalık İzni</option> <option value="sick">🏥 {translate('::App.Platform.Intranet.LeaveRequestModal.SickLeave')}</option>
<option value="unpaid">💼 Ücretsiz İzin</option> <option value="unpaid">💼 {translate('::App.Platform.Intranet.LeaveRequestModal.UnpaidLeave')}</option>
<option value="other">📋 Diğer</option> <option value="other">📋 {translate('::App.Platform.Intranet.LeaveRequestModal.Other')}</option>
</select> </select>
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Başlangıç Tarihi * {translate('::App.Platform.Intranet.LeaveRequestModal.StartDate')}
</label> </label>
<input <input
type="date" type="date"
@ -73,7 +75,7 @@ const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Bitiş Tarihi * {translate('::App.Platform.Intranet.LeaveRequestModal.EndDate')}
</label> </label>
<input <input
type="date" type="date"
@ -85,12 +87,12 @@ const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
ıklama * {translate('::App.Platform.Intranet.LeaveRequestModal.Description')}
</label> </label>
<textarea <textarea
required required
rows={3} rows={3}
placeholder="İzin sebebinizi yazınız..." placeholder={translate('::App.Platform.Intranet.LeaveRequestModal.ReasonPlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
@ -101,13 +103,13 @@ const LeaveRequestModal: React.FC<LeaveRequestModalProps> = ({ onClose, onSubmit
onClick={onClose} onClick={onClose}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
> >
İptal {translate('::App.Platform.Intranet.LeaveRequestModal.Cancel')}
</button> </button>
<button <button
type="submit" type="submit"
className="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors" className="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors"
> >
Gönder {translate('::App.Platform.Intranet.LeaveRequestModal.Submit')}
</button> </button>
</div> </div>
</form> </form>

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes } from 'react-icons/fa' import { FaTimes } from 'react-icons/fa'
@ -8,6 +9,7 @@ interface OvertimeRequestModalProps {
} }
const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, onSubmit }) => { const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, onSubmit }) => {
const { translate } = useLocalization();
return ( return (
<> <>
<motion.div <motion.div
@ -27,7 +29,7 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
> >
<div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10"> <div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white"> <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Yeni Mesai Talebi {translate('::App.Platform.Intranet.OvertimeRequestModal.Title')}
</h2> </h2>
<button <button
onClick={onClose} onClick={onClose}
@ -46,7 +48,7 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
> >
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Mesai Tarihi * {translate('::App.Platform.Intranet.OvertimeRequestModal.Date')}
</label> </label>
<input <input
type="date" type="date"
@ -58,7 +60,7 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Başlangıç Saati * {translate('::App.Platform.Intranet.OvertimeRequestModal.StartTime')}
</label> </label>
<input <input
type="time" type="time"
@ -68,7 +70,7 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Bitiş Saati * {translate('::App.Platform.Intranet.OvertimeRequestModal.EndTime')}
</label> </label>
<input <input
type="time" type="time"
@ -80,12 +82,12 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
ıklama * {translate('::App.Platform.Intranet.OvertimeRequestModal.Description')}
</label> </label>
<textarea <textarea
required required
rows={3} rows={3}
placeholder="Mesai sebebinizi yazınız..." placeholder={translate('::App.Platform.Intranet.OvertimeRequestModal.ReasonPlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
@ -96,13 +98,13 @@ const OvertimeRequestModal: React.FC<OvertimeRequestModalProps> = ({ onClose, on
onClick={onClose} onClick={onClose}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
> >
İptal {translate('::App.Platform.Intranet.OvertimeRequestModal.Cancel')}
</button> </button>
<button <button
type="submit" type="submit"
className="flex-1 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-lg transition-colors" className="flex-1 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-lg transition-colors"
> >
Gönder {translate('::App.Platform.Intranet.OvertimeRequestModal.Submit')}
</button> </button>
</div> </div>
</form> </form>

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { FaTimes } from 'react-icons/fa' import { FaTimes } from 'react-icons/fa'
@ -8,6 +9,7 @@ interface ReservationRequestModalProps {
} }
const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClose, onSubmit }) => { const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClose, onSubmit }) => {
const { translate } = useLocalization();
return ( return (
<> <>
<motion.div <motion.div
@ -27,7 +29,7 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
> >
<div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10"> <div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between sticky top-0 bg-white dark:bg-gray-800 z-10">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white"> <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Yeni Rezervasyon Talebi {translate('::App.Platform.Intranet.ReservationRequestModal.Title')}
</h2> </h2>
<button <button
onClick={onClose} onClick={onClose}
@ -46,27 +48,27 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
> >
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Rezervasyon Türü * {translate('::App.Platform.Intranet.ReservationRequestModal.Type')}
</label> </label>
<select <select
required required
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
> >
<option value="">Seçiniz</option> <option value="">{translate('::App.Platform.Intranet.ReservationRequestModal.Select')}</option>
<option value="room">🏢 Toplantı Odası</option> <option value="room">🏢 {translate('::App.Platform.Intranet.ReservationRequestModal.Room')}</option>
<option value="vehicle">🚗 Şirket Aracı</option> <option value="vehicle">🚗 {translate('::App.Platform.Intranet.ReservationRequestModal.Vehicle')}</option>
<option value="equipment"> Ekipman</option> <option value="equipment"> {translate('::App.Platform.Intranet.ReservationRequestModal.Equipment')}</option>
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Kaynak Adı * {translate('::App.Platform.Intranet.ReservationRequestModal.ResourceName')}
</label> </label>
<input <input
type="text" type="text"
required required
placeholder="Örn: Toplantı Salonu A, Şirket Aracı - Plaka, Kamera Seti..." placeholder={translate('::App.Platform.Intranet.ReservationRequestModal.ResourceNamePlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
@ -74,7 +76,7 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Başlangıç Tarihi * {translate('::App.Platform.Intranet.ReservationRequestModal.StartDate')}
</label> </label>
<input <input
type="datetime-local" type="datetime-local"
@ -84,7 +86,7 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Bitiş Tarihi * {translate('::App.Platform.Intranet.ReservationRequestModal.EndDate')}
</label> </label>
<input <input
type="datetime-local" type="datetime-local"
@ -96,42 +98,42 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Amaç * {translate('::App.Platform.Intranet.ReservationRequestModal.Purpose')}
</label> </label>
<input <input
type="text" type="text"
required required
placeholder="Rezervasyon amacını belirtiniz..." placeholder={translate('::App.Platform.Intranet.ReservationRequestModal.PurposePlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Katılımcı Sayısı {translate('::App.Platform.Intranet.ReservationRequestModal.ParticipantCount')}
</label> </label>
<input <input
type="number" type="number"
min="1" min="1"
placeholder="Toplantı odası için katılımcı sayısı (opsiyonel)" placeholder={translate('::App.Platform.Intranet.ReservationRequestModal.ParticipantCountPlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Notlar {translate('::App.Platform.Intranet.ReservationRequestModal.Notes')}
</label> </label>
<textarea <textarea
rows={3} rows={3}
placeholder="Ek bilgi veya özel istekler (opsiyonel)..." placeholder={translate('::App.Platform.Intranet.ReservationRequestModal.NotesPlaceholder')}
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
/> />
</div> </div>
<div className="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-3"> <div className="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-3">
<p className="text-sm text-blue-700 dark:text-blue-300"> <p className="text-sm text-blue-700 dark:text-blue-300">
Rezervasyon talebiniz yönetici onayına sunulacaktır. {translate('::App.Platform.Intranet.ReservationRequestModal.Info')}
</p> </p>
</div> </div>
@ -141,13 +143,13 @@ const ReservationRequestModal: React.FC<ReservationRequestModalProps> = ({ onClo
onClick={onClose} onClick={onClose}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
> >
İptal {translate('::App.Platform.Intranet.ReservationRequestModal.Cancel')}
</button> </button>
<button <button
type="submit" type="submit"
className="flex-1 px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors" className="flex-1 px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors"
> >
Gönder {translate('::App.Platform.Intranet.ReservationRequestModal.Submit')}
</button> </button>
</div> </div>
</form> </form>

View file

@ -9,7 +9,9 @@ interface SurveyModalProps {
onSubmit: (answers: SurveyAnswerDto[]) => void onSubmit: (answers: SurveyAnswerDto[]) => void
} }
import { useLocalization } from '@/utils/hooks/useLocalization'
const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit }) => { const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit }) => {
const { translate } = useLocalization();
const [answers, setAnswers] = useState<{ [questionId: string]: any }>({}) const [answers, setAnswers] = useState<{ [questionId: string]: any }>({})
const [errors, setErrors] = useState<{ [questionId: string]: string }>({}) const [errors, setErrors] = useState<{ [questionId: string]: string }>({})
@ -33,7 +35,7 @@ const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit })
survey.questions.forEach((question) => { survey.questions.forEach((question) => {
if (question.isRequired && (!answers[question.id] || answers[question.id] === '')) { if (question.isRequired && (!answers[question.id] || answers[question.id] === '')) {
newErrors[question.id] = 'Bu alan zorunludur' newErrors[question.id] = translate('::App.Platform.Intranet.SurveyModal.RequiredField')
} }
}) })
@ -159,7 +161,7 @@ const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit })
className={`w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 ${ className={`w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 ${
hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600' hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
}`} }`}
placeholder="Cevabınızı yazın..." placeholder={translate('::App.Platform.Intranet.SurveyModal.AnswerPlaceholder')}
/> />
{hasError && ( {hasError && (
<p className="text-sm text-red-600 dark:text-red-400">{errors[question.id]}</p> <p className="text-sm text-red-600 dark:text-red-400">{errors[question.id]}</p>
@ -180,7 +182,7 @@ const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit })
className={`w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 ${ className={`w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 ${
hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600' hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
}`} }`}
placeholder="Yorumlarınızı buraya yazabilirsiniz..." placeholder={translate('::App.Platform.Intranet.SurveyModal.CommentPlaceholder')}
/> />
{hasError && ( {hasError && (
<p className="text-sm text-red-600 dark:text-red-400">{errors[question.id]}</p> <p className="text-sm text-red-600 dark:text-red-400">{errors[question.id]}</p>
@ -254,13 +256,13 @@ const SurveyModal: React.FC<SurveyModalProps> = ({ survey, onClose, onSubmit })
onClick={onClose} onClick={onClose}
className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
> >
İptal {translate('::App.Platform.Intranet.SurveyModal.Cancel')}
</button> </button>
<button <button
type="submit" type="submit"
className="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors" className="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors"
> >
Anketi Gönder {translate('::App.Platform.Intranet.SurveyModal.Submit')}
</button> </button>
</div> </div>
</form> </form>

View file

@ -3,6 +3,7 @@ import { FaKey, FaPlus } from 'react-icons/fa'
import { ReservationDto } from '@/proxy/intranet/models' import { ReservationDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface ActiveReservationsProps { interface ActiveReservationsProps {
reservations: ReservationDto[] reservations: ReservationDto[]
@ -14,13 +15,14 @@ const ActiveReservations: React.FC<ActiveReservationsProps> = ({
onNewReservation, onNewReservation,
}) => { }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization()
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaKey className="w-5 h-5" /> <FaKey className="w-5 h-5" />
Aktif Rezervasyonlar {translate('::App.Platform.Intranet.Widgets.ActiveReservations.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
@ -52,7 +54,7 @@ const ActiveReservations: React.FC<ActiveReservationsProps> = ({
))} ))}
{reservations.filter((r) => r.status === 'approved').length === 0 && ( {reservations.filter((r) => r.status === 'approved').length === 0 && (
<p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4"> <p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
Aktif rezervasyon yok {translate('::App.Platform.Intranet.Widgets.ActiveReservations.NoActive')}
</p> </p>
)} )}
@ -61,7 +63,7 @@ const ActiveReservations: React.FC<ActiveReservationsProps> = ({
className="w-full mt-3 px-4 py-2 bg-green-600 hover:bg-green-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2" className="w-full mt-3 px-4 py-2 bg-green-600 hover:bg-green-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2"
> >
<FaPlus className="w-4 h-4" /> <FaPlus className="w-4 h-4" />
Yeni Rezervasyon {translate('::App.Platform.Intranet.Widgets.ActiveReservations.NewReservation')}
</button> </button>
</div> </div>
</div> </div>

View file

@ -4,6 +4,7 @@ import dayjs from 'dayjs'
import { SurveyDto } from '@/proxy/intranet/models' import { SurveyDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface ActiveSurveysProps { interface ActiveSurveysProps {
surveys?: SurveyDto[] surveys?: SurveyDto[]
@ -12,6 +13,7 @@ interface ActiveSurveysProps {
const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey }) => { const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization()
return ( 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"> <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">
@ -20,7 +22,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaClipboardCheck className="w-5 h-5" /> <FaClipboardCheck className="w-5 h-5" />
Aktif Anketler {translate('::App.Platform.Intranet.Widgets.ActiveSurveys.Title')}
</h2> </h2>
</div> </div>
@ -53,7 +55,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300' : 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300'
}`} }`}
> >
{daysLeft > 0 ? `${daysLeft} gün` : 'Son gün'} {daysLeft > 0 ? translate('::App.Platform.Intranet.Widgets.ActiveSurveys.DaysLeft', { count: daysLeft }) : translate('::App.Platform.Intranet.Widgets.ActiveSurveys.LastDay')}
</div> </div>
</div> </div>
@ -64,7 +66,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
<FaQuestionCircle className="w-3 h-3 text-blue-600 dark:text-blue-400" /> <FaQuestionCircle className="w-3 h-3 text-blue-600 dark:text-blue-400" />
</div> </div>
<div> <div>
<p className="text-xs text-gray-500 dark:text-gray-400">Sorular</p> <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"> <p className="font-semibold text-gray-900 dark:text-white">
{survey.questions.length} {survey.questions.length}
</p> </p>
@ -76,7 +78,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
<FaUsers className="w-3 h-3 text-green-600 dark:text-green-400" /> <FaUsers className="w-3 h-3 text-green-600 dark:text-green-400" />
</div> </div>
<div> <div>
<p className="text-xs text-gray-500 dark:text-gray-400">Yanıtlar</p> <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"> <p className="font-semibold text-gray-900 dark:text-white">
{survey.responses} {survey.responses}
</p> </p>
@ -88,7 +90,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
<FaClock className="w-3 h-3 text-purple-600 dark:text-purple-400" /> <FaClock className="w-3 h-3 text-purple-600 dark:text-purple-400" />
</div> </div>
<div> <div>
<p className="text-xs text-gray-500 dark:text-gray-400">Süre</p> <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> <p className="font-semibold text-gray-900 dark:text-white">~5dk</p>
</div> </div>
</div> </div>
@ -97,7 +99,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
{/* Progress Bar */} {/* Progress Bar */}
<div className="mb-4"> <div className="mb-4">
<div className="flex justify-between text-xs mb-1"> <div className="flex justify-between text-xs mb-1">
<span className="text-gray-600 dark:text-gray-400">Tamamlanma oranı</span> <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"> <span className="text-gray-800 dark:text-gray-200 font-medium">
{Math.round((survey.responses / 100) * 100)}% {Math.round((survey.responses / 100) * 100)}%
</span> </span>
@ -118,7 +120,7 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
{/* Action Button */} {/* Action Button */}
<button className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white text-sm font-medium rounded-lg transition-all duration-300 transform group-hover:scale-[1.02] shadow-sm hover:shadow-md"> <button className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white text-sm font-medium rounded-lg transition-all duration-300 transform group-hover:scale-[1.02] shadow-sm hover:shadow-md">
Anketi Doldur {translate('::App.Platform.Intranet.Widgets.ActiveSurveys.FillSurvey')}
<FaArrowRight className="w-3 h-3 transition-transform group-hover:translate-x-1" /> <FaArrowRight className="w-3 h-3 transition-transform group-hover:translate-x-1" />
</button> </button>
</div> </div>
@ -132,10 +134,10 @@ const ActiveSurveys: React.FC<ActiveSurveysProps> = ({ surveys, onTakeSurvey })
<FaClipboardCheck className="w-8 h-8 text-gray-400" /> <FaClipboardCheck className="w-8 h-8 text-gray-400" />
</div> </div>
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2"> <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
Aktif anket bulunmuyor {translate('::App.Platform.Intranet.Widgets.ActiveSurveys.NoActive')}
</h3> </h3>
<p className="text-sm text-gray-500 dark:text-gray-400"> <p className="text-sm text-gray-500 dark:text-gray-400">
Yeni anketler eklendiğinde burada görünecektir. {translate('::App.Platform.Intranet.Widgets.ActiveSurveys.WillAppearHere')}
</p> </p>
</div> </div>
)} )}

View file

@ -2,6 +2,7 @@ import React from 'react'
import { FaBell, FaClipboardCheck, FaEye } from 'react-icons/fa' import { FaBell, FaClipboardCheck, FaEye } from 'react-icons/fa'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { AnnouncementDto } from '@/proxy/intranet/models' import { AnnouncementDto } from '@/proxy/intranet/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface AnnouncementsProps { interface AnnouncementsProps {
announcements: AnnouncementDto[] announcements: AnnouncementDto[]
@ -10,6 +11,7 @@ interface AnnouncementsProps {
const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnouncementClick }) => { const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnouncementClick }) => {
const pinnedAnnouncements = announcements.filter((a) => a.isPinned).slice(0, 3) const pinnedAnnouncements = announcements.filter((a) => a.isPinned).slice(0, 3)
const { translate } = useLocalization();
const getCategoryColor = (category: string) => { const getCategoryColor = (category: string) => {
const colors: Record<string, string> = { const colors: Record<string, string> = {
@ -28,7 +30,7 @@ const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnounce
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaBell className="w-5 h-5" /> <FaBell className="w-5 h-5" />
Önemli Duyurular {translate('::App.Platform.Intranet.Widgets.Announcements.Title')}
</h2> </h2>
</div> </div>
</div> </div>
@ -53,7 +55,7 @@ const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnounce
<span <span
className={`px-2 py-1 text-xs rounded-full ${getCategoryColor(announcement.category)}`} className={`px-2 py-1 text-xs rounded-full ${getCategoryColor(announcement.category)}`}
> >
{announcement.category} {translate(`::App.Platform.Intranet.Widgets.Announcements.Category.${announcement.category.charAt(0).toUpperCase() + announcement.category.slice(1)}`, announcement.category)}
</span> </span>
</div> </div>
<p className="text-sm text-gray-600 dark:text-gray-400 line-clamp-2"> <p className="text-sm text-gray-600 dark:text-gray-400 line-clamp-2">
@ -80,10 +82,10 @@ const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnounce
<FaClipboardCheck className="w-8 h-8 text-gray-400" /> <FaClipboardCheck className="w-8 h-8 text-gray-400" />
</div> </div>
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2"> <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
Aktif duyuru bulunmuyor {translate('::App.Platform.Intranet.Widgets.Announcements.NoActive')}
</h3> </h3>
<p className="text-sm text-gray-500 dark:text-gray-400"> <p className="text-sm text-gray-500 dark:text-gray-400">
Yeni duyurular eklendiğinde burada görünecektir. {translate('::App.Platform.Intranet.Widgets.Announcements.WillAppearHere')}
</p> </p>
</div> </div>
)} )}

View file

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import { FaDollarSign, FaPlus } from 'react-icons/fa' import { FaDollarSign, FaPlus } from 'react-icons/fa'
import { ExpensesDto } from '@/proxy/intranet/models' import { ExpensesDto } from '@/proxy/intranet/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface ExpenseManagementProps { interface ExpenseManagementProps {
expenses: ExpensesDto expenses: ExpensesDto
@ -8,23 +9,24 @@ interface ExpenseManagementProps {
} }
const ExpenseManagement: React.FC<ExpenseManagementProps> = ({ expenses, onNewExpense }) => { const ExpenseManagement: React.FC<ExpenseManagementProps> = ({ expenses, onNewExpense }) => {
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaDollarSign className="w-5 h-5" /> <FaDollarSign className="w-5 h-5" />
Harcama Yönetimi {translate('::App.Platform.Intranet.Widgets.ExpenseManagement.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
{/* Harcama özeti */} {/* Harcama özeti */}
<div className="p-3 bg-emerald-50 dark:bg-emerald-900/20 rounded-lg border border-emerald-200 dark:border-emerald-800 mb-4"> <div className="p-3 bg-emerald-50 dark:bg-emerald-900/20 rounded-lg border border-emerald-200 dark:border-emerald-800 mb-4">
<p className="text-xs text-gray-600 dark:text-gray-400">Bu Ay Toplam</p> <p className="text-xs text-gray-600 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.ExpenseManagement.ThisMonthTotal')}</p>
<p className="text-2xl font-bold text-emerald-600 dark:text-emerald-400"> <p className="text-2xl font-bold text-emerald-600 dark:text-emerald-400">
{expenses.totalRequested.toLocaleString('tr-TR')} {expenses.totalRequested.toLocaleString('tr-TR')}
</p> </p>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1"> <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
{expenses.totalApproved.toLocaleString('tr-TR')} onaylandı {expenses.totalApproved.toLocaleString('tr-TR')} {translate('::App.Platform.Intranet.Widgets.ExpenseManagement.Approved')}
</p> </p>
</div> </div>
@ -63,10 +65,10 @@ const ExpenseManagement: React.FC<ExpenseManagementProps> = ({ expenses, onNewEx
}`} }`}
> >
{expense.status === 'approved' {expense.status === 'approved'
? 'Onaylandı' ? translate('::App.Platform.Intranet.Widgets.ExpenseManagement.Status.Approved')
: expense.status === 'pending' : expense.status === 'pending'
? 'Bekliyor' ? translate('::App.Platform.Intranet.Widgets.ExpenseManagement.Status.Pending')
: 'Reddedildi'} : translate('::App.Platform.Intranet.Widgets.ExpenseManagement.Status.Rejected')}
</span> </span>
</div> </div>
</div> </div>
@ -78,7 +80,7 @@ const ExpenseManagement: React.FC<ExpenseManagementProps> = ({ expenses, onNewEx
className="w-full mt-3 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2" className="w-full mt-3 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2"
> >
<FaPlus className="w-4 h-4" /> <FaPlus className="w-4 h-4" />
Yeni Harcama Talebi {translate('::App.Platform.Intranet.Widgets.ExpenseManagement.NewExpense')}
</button> </button>
</div> </div>
</div> </div>

View file

@ -4,6 +4,7 @@ import { LeaveDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { LeaveStatusEnum, LeaveTypeEnum } from '@/types/intranet' import { LeaveStatusEnum, LeaveTypeEnum } from '@/types/intranet'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface LeaveManagementProps { interface LeaveManagementProps {
leaves: LeaveDto[] leaves: LeaveDto[]
@ -12,25 +13,26 @@ interface LeaveManagementProps {
const LeaveManagement: React.FC<LeaveManagementProps> = ({ leaves, onNewLeave }) => { const LeaveManagement: React.FC<LeaveManagementProps> = ({ leaves, onNewLeave }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaCalendarAlt className="w-5 h-5" /> <FaCalendarAlt className="w-5 h-5" />
İzin Yönetimi {translate('::App.Platform.Intranet.Widgets.LeaveManagement.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
{/* İzin bakiye özeti */} {/* İzin bakiye özeti */}
<div className="grid grid-cols-2 gap-2 mb-4"> <div className="grid grid-cols-2 gap-2 mb-4">
<div className="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800"> <div className="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800">
<p className="text-xs text-gray-600 dark:text-gray-400">Yıllık İzin</p> <p className="text-xs text-gray-600 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.LeaveManagement.AnnualLeave')}</p>
<p className="text-lg font-bold text-blue-600 dark:text-blue-400">12 gün</p> <p className="text-lg font-bold text-blue-600 dark:text-blue-400">12 {translate('::App.Platform.Intranet.Widgets.LeaveManagement.Day')}</p>
</div> </div>
<div className="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800"> <div className="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800">
<p className="text-xs text-gray-600 dark:text-gray-400">Hastalık İzni</p> <p className="text-xs text-gray-600 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.LeaveManagement.SickLeave')}</p>
<p className="text-lg font-bold text-green-600 dark:text-green-400">8 gün</p> <p className="text-lg font-bold text-green-600 dark:text-green-400">8 {translate('::App.Platform.Intranet.Widgets.LeaveManagement.Day')}</p>
</div> </div>
</div> </div>
@ -44,13 +46,13 @@ const LeaveManagement: React.FC<LeaveManagementProps> = ({ leaves, onNewLeave })
<div className="flex items-start justify-between mb-1"> <div className="flex items-start justify-between mb-1">
<h4 className="text-sm font-medium text-gray-900 dark:text-white"> <h4 className="text-sm font-medium text-gray-900 dark:text-white">
{leave.leaveType === LeaveTypeEnum.Annual {leave.leaveType === LeaveTypeEnum.Annual
? '🏖️ Yıllık' ? `🏖️ ${translate('::App.Platform.Intranet.Widgets.LeaveManagement.Annual')}`
: leave.leaveType === LeaveTypeEnum.Sick : leave.leaveType === LeaveTypeEnum.Sick
? '🏥 Hastalık' ? `🏥 ${translate('::App.Platform.Intranet.Widgets.LeaveManagement.Sick')}`
: leave.leaveType === LeaveTypeEnum.Unpaid : leave.leaveType === LeaveTypeEnum.Unpaid
? '💼 Ücretsiz' ? `💼 ${translate('::App.Platform.Intranet.Widgets.LeaveManagement.Unpaid')}`
: '📋 Diğer'}{' '} : `📋 ${translate('::App.Platform.Intranet.Widgets.LeaveManagement.Other')}`}{' '}
İzin {translate('::App.Platform.Intranet.Widgets.LeaveManagement.Leave')}
</h4> </h4>
<span <span
className={`text-xs px-2 py-1 rounded-full ${ className={`text-xs px-2 py-1 rounded-full ${
@ -62,15 +64,15 @@ const LeaveManagement: React.FC<LeaveManagementProps> = ({ leaves, onNewLeave })
}`} }`}
> >
{leave.status === LeaveStatusEnum.Approved {leave.status === LeaveStatusEnum.Approved
? 'Onaylandı' ? translate('::App.Platform.Intranet.Widgets.LeaveManagement.Status.Approved')
: leave.status === LeaveStatusEnum.Pending : leave.status === LeaveStatusEnum.Pending
? 'Bekliyor' ? translate('::App.Platform.Intranet.Widgets.LeaveManagement.Status.Pending')
: 'Reddedildi'} : translate('::App.Platform.Intranet.Widgets.LeaveManagement.Status.Rejected')}
</span> </span>
</div> </div>
<p className="text-xs text-gray-600 dark:text-gray-400"> <p className="text-xs text-gray-600 dark:text-gray-400">
{currentLocalDate(leave.startDate, currentLocale || 'tr')} - {currentLocalDate(leave.endDate, currentLocale || 'tr')}{' '} {currentLocalDate(leave.startDate, currentLocale || 'tr')} - {currentLocalDate(leave.endDate, currentLocale || 'tr')}{' '}
({leave.totalDays} gün) ({leave.totalDays} {translate('::App.Platform.Intranet.Widgets.LeaveManagement.Day')})
</p> </p>
</div> </div>
))} ))}
@ -81,7 +83,7 @@ const LeaveManagement: React.FC<LeaveManagementProps> = ({ leaves, onNewLeave })
className="w-full mt-3 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2" className="w-full mt-3 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2"
> >
<FaPlus className="w-4 h-4" /> <FaPlus className="w-4 h-4" />
Yeni İzin Talebi {translate('::App.Platform.Intranet.Widgets.LeaveManagement.NewLeaveRequest')}
</button> </button>
</div> </div>
</div> </div>

View file

@ -6,11 +6,13 @@ import { Badge } from '@/components/ui'
import { MealDto } from '@/proxy/intranet/models' import { MealDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
dayjs.extend(isBetween) dayjs.extend(isBetween)
const MealWeeklyMenu: React.FC<{ meals: MealDto[] }> = ({ meals }) => { const MealWeeklyMenu: React.FC<{ meals: MealDto[] }> = ({ meals }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
@ -18,7 +20,7 @@ const MealWeeklyMenu: React.FC<{ meals: MealDto[] }> = ({ meals }) => {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaUtensils className="w-5 h-5" /> <FaUtensils className="w-5 h-5" />
Haftalık Menü {translate('::App.Platform.Intranet.Widgets.MealWeeklyMenu.Title')}
</h2> </h2>
</div> </div>
</div> </div>
@ -40,7 +42,7 @@ const MealWeeklyMenu: React.FC<{ meals: MealDto[] }> = ({ meals }) => {
</h3> </h3>
{isToday && ( {isToday && (
<span className="text-xs bg-orange-500 text-white px-2 py-0.5 rounded-full"> <span className="text-xs bg-orange-500 text-white px-2 py-0.5 rounded-full">
Bugün {translate('::App.Platform.Intranet.Widgets.MealWeeklyMenu.Today')}
</span> </span>
)} )}
</div> </div>
@ -67,7 +69,7 @@ const MealWeeklyMenu: React.FC<{ meals: MealDto[] }> = ({ meals }) => {
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<p className="text-xs text-gray-500 dark:text-gray-400"> <p className="text-xs text-gray-500 dark:text-gray-400">
Haftalık menü henüz hazırlanmamış. Lütfen daha sonra tekrar kontrol edin. {translate('::App.Platform.Intranet.Widgets.MealWeeklyMenu.NotReady')}
</p> </p>
</div> </div>
</div> </div>

View file

@ -4,6 +4,7 @@ import { OvertimeDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { LeaveStatusEnum } from '@/types/intranet' import { LeaveStatusEnum } from '@/types/intranet'
import { useLocalization } from '@/utils/hooks/useLocalization'
interface OvertimeManagementProps { interface OvertimeManagementProps {
overtimes: OvertimeDto[] overtimes: OvertimeDto[]
@ -12,21 +13,22 @@ interface OvertimeManagementProps {
const OvertimeManagement: React.FC<OvertimeManagementProps> = ({ overtimes, onNewOvertime }) => { const OvertimeManagement: React.FC<OvertimeManagementProps> = ({ overtimes, onNewOvertime }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaClock className="w-5 h-5" /> <FaClock className="w-5 h-5" />
Mesai Yönetimi {translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
{/* Mesai özeti */} {/* Mesai özeti */}
<div className="p-3 bg-orange-50 dark:bg-orange-900/20 rounded-lg border border-orange-200 dark:border-orange-800 mb-4"> <div className="p-3 bg-orange-50 dark:bg-orange-900/20 rounded-lg border border-orange-200 dark:border-orange-800 mb-4">
<p className="text-xs text-gray-600 dark:text-gray-400">Bu Ay Toplam</p> <p className="text-xs text-gray-600 dark:text-gray-400">{translate('::App.Platform.Intranet.Widgets.OvertimeManagement.ThisMonthTotal')}</p>
<p className="text-2xl font-bold text-orange-600 dark:text-orange-400">24 saat</p> <p className="text-2xl font-bold text-orange-600 dark:text-orange-400">24 {translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Hour')}</p>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">20 onaylandı, 4 bekliyor</p> <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">20 {translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Status.Approved')}, 4 {translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Status.Pending')}</p>
</div> </div>
{/* Son mesai talepleri */} {/* Son mesai talepleri */}
@ -50,10 +52,10 @@ const OvertimeManagement: React.FC<OvertimeManagementProps> = ({ overtimes, onNe
}`} }`}
> >
{overtime.status === LeaveStatusEnum.Approved {overtime.status === LeaveStatusEnum.Approved
? 'Onaylandı' ? translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Status.Approved')
: overtime.status === LeaveStatusEnum.Pending : overtime.status === LeaveStatusEnum.Pending
? 'Bekliyor' ? translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Status.Pending')
: 'Reddedildi'} : translate('::App.Platform.Intranet.Widgets.OvertimeManagement.Status.Rejected')}
</span> </span>
</div> </div>
<p className="text-xs text-gray-600 dark:text-gray-400"> <p className="text-xs text-gray-600 dark:text-gray-400">
@ -68,7 +70,7 @@ const OvertimeManagement: React.FC<OvertimeManagementProps> = ({ overtimes, onNe
className="w-full mt-3 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2" className="w-full mt-3 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white text-sm rounded-lg transition-colors flex items-center justify-center gap-2"
> >
<FaPlus className="w-4 h-4" /> <FaPlus className="w-4 h-4" />
Yeni Mesai Talebi {translate('::App.Platform.Intranet.Widgets.OvertimeManagement.NewOvertimeRequest')}
</button> </button>
</div> </div>
</div> </div>

View file

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import { FaChartBar, FaClock, FaUser } from 'react-icons/fa' import { FaChartBar, FaClock, FaUser } from 'react-icons/fa'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { PriorityEnum, TaskStatusEnum } from '@/types/intranet' import { PriorityEnum, TaskStatusEnum } from '@/types/intranet'
import { ProjectTaskDto } from '@/proxy/intranet/models' import { ProjectTaskDto } from '@/proxy/intranet/models'
@ -11,6 +12,7 @@ interface PriorityTasksProps {
const PriorityTasks: React.FC<PriorityTasksProps> = ({ tasks }) => { const PriorityTasks: React.FC<PriorityTasksProps> = ({ tasks }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
const getPriorityColor = (priority: PriorityEnum) => { const getPriorityColor = (priority: PriorityEnum) => {
const colors: Record<PriorityEnum, string> = { const colors: Record<PriorityEnum, string> = {
@ -28,7 +30,7 @@ const PriorityTasks: React.FC<PriorityTasksProps> = ({ tasks }) => {
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaChartBar className="w-5 h-5" /> <FaChartBar className="w-5 h-5" />
Öncelikli Görevler {translate('::App.Platform.Intranet.Widgets.PriorityTasks.Title')}
</h2> </h2>
</div> </div>
<div className="divide-y divide-gray-200 dark:divide-gray-700"> <div className="divide-y divide-gray-200 dark:divide-gray-700">
@ -47,10 +49,10 @@ const PriorityTasks: React.FC<PriorityTasksProps> = ({ tasks }) => {
<span <span
className={`px-2 py-0.5 text-xs rounded ${getPriorityColor(task.priority)}`} className={`px-2 py-0.5 text-xs rounded ${getPriorityColor(task.priority)}`}
> >
{task.priority === PriorityEnum.Urgent && '🔥 Acil'} {task.priority === PriorityEnum.Urgent && translate('::App.Platform.Intranet.Widgets.PriorityTasks.Urgent')}
{task.priority === PriorityEnum.High && 'Yüksek'} {task.priority === PriorityEnum.High && translate('::App.Platform.Intranet.Widgets.PriorityTasks.High')}
{task.priority === PriorityEnum.Normal && 'Orta'} {task.priority === PriorityEnum.Normal && translate('::App.Platform.Intranet.Widgets.PriorityTasks.Normal')}
{task.priority === PriorityEnum.Low && 'Düşük'} {task.priority === PriorityEnum.Low && translate('::App.Platform.Intranet.Widgets.PriorityTasks.Low')}
</span> </span>
</div> </div>
<p className="text-xs text-gray-600 dark:text-gray-400 mb-2">{task.description}</p> <p className="text-xs text-gray-600 dark:text-gray-400 mb-2">{task.description}</p>
@ -61,7 +63,7 @@ const PriorityTasks: React.FC<PriorityTasksProps> = ({ tasks }) => {
</span> </span>
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<FaUser className="w-3 h-3" /> <FaUser className="w-3 h-3" />
{task.employee.name || 'Atanmadı'} {task.employee.name || translate('::App.Platform.Intranet.Widgets.PriorityTasks.Unassigned')}
</span> </span>
</div> </div>
</div> </div>

View file

@ -3,6 +3,7 @@ import { FaFileAlt, FaDownload } from 'react-icons/fa'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { DocumentDto } from '@/proxy/intranet/models' import { DocumentDto } from '@/proxy/intranet/models'
import { getFileIcon, getFileType } from '@/proxy/intranet/utils' import { getFileIcon, getFileType } from '@/proxy/intranet/utils'
import { useLocalization } from '@/utils/hooks/useLocalization'
const formatFileSize = (bytes: number): string => { const formatFileSize = (bytes: number): string => {
if (bytes === 0) return '0 B' if (bytes === 0) return '0 B'
@ -13,13 +14,14 @@ const formatFileSize = (bytes: number): string => {
} }
const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents }) => { const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents }) => {
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaFileAlt className="w-5 h-5" /> <FaFileAlt className="w-5 h-5" />
Son Dokümanlar {translate('::App.Platform.Intranet.Widgets.RecentDocuments.Title')}
</h2> </h2>
</div> </div>
</div> </div>
@ -48,7 +50,7 @@ const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents })
{doc.isReadOnly && ( {doc.isReadOnly && (
<> <>
<span></span> <span></span>
<span className="text-orange-500">🔒 Salt okunur</span> <span className="text-orange-500">🔒 {translate('::App.Platform.Intranet.Widgets.RecentDocuments.ReadOnly')}</span>
</> </>
)} )}
</div> </div>
@ -62,7 +64,7 @@ const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents })
link.click() link.click()
}} }}
className="p-2 hover:bg-blue-100 dark:hover:bg-blue-900/30 rounded-lg transition-colors group" className="p-2 hover:bg-blue-100 dark:hover:bg-blue-900/30 rounded-lg transition-colors group"
title="İndir" title={translate('::App.Platform.Intranet.Widgets.RecentDocuments.Download')}
> >
<FaDownload className="w-5 h-5 text-gray-600 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors" /> <FaDownload className="w-5 h-5 text-gray-600 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors" />
</button> </button>
@ -71,7 +73,7 @@ const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents })
)) ))
) : ( ) : (
<div className="p-4 text-center text-sm text-gray-500 dark:text-gray-400"> <div className="p-4 text-center text-sm text-gray-500 dark:text-gray-400">
Gösterilecek doküman yok. {translate('::App.Platform.Intranet.Widgets.RecentDocuments.NoDocuments')}
</div> </div>
)} )}
</div> </div>

View file

@ -1,24 +1,26 @@
import React from 'react' import React from 'react'
import { FaTruck } from 'react-icons/fa' import { FaTruck } from 'react-icons/fa'
import { ShuttleRouteDto } from '@/proxy/intranet/models' import { ShuttleRouteDto } from '@/proxy/intranet/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
const ShuttleRoute: React.FC<{ shuttleRoutes: ShuttleRouteDto[] }> = ({ shuttleRoutes }) => { const ShuttleRoute: React.FC<{ shuttleRoutes: ShuttleRouteDto[] }> = ({ shuttleRoutes }) => {
const morningShuttles = shuttleRoutes.filter((s) => s.type === 'morning') const morningShuttles = shuttleRoutes.filter((s) => s.type === 'morning')
const eveningShuttles = shuttleRoutes.filter((s) => s.type === 'evening') const eveningShuttles = shuttleRoutes.filter((s) => s.type === 'evening')
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaTruck className="w-5 h-5" /> <FaTruck className="w-5 h-5" />
Servis Saatleri {translate('::App.Platform.Intranet.Widgets.ShuttleRoute.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-4"> <div className="p-4 space-y-4">
{/* Sabah Servisleri */} {/* Sabah Servisleri */}
<div> <div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2"> <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2">
🌅 Sabah Servisleri 🌅 {translate('::App.Platform.Intranet.Widgets.ShuttleRoute.Morning')}
</h3> </h3>
<div className="space-y-2"> <div className="space-y-2">
{morningShuttles.slice(0, 2).map((shuttle) => ( {morningShuttles.slice(0, 2).map((shuttle) => (
@ -52,7 +54,7 @@ const ShuttleRoute: React.FC<{ shuttleRoutes: ShuttleRouteDto[] }> = ({ shuttleR
: 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300' : 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300'
}`} }`}
> >
{shuttle.available} yer {shuttle.available} {translate('::App.Platform.Intranet.Widgets.ShuttleRoute.Seat')}
</span> </span>
</div> </div>
</div> </div>
@ -63,7 +65,7 @@ const ShuttleRoute: React.FC<{ shuttleRoutes: ShuttleRouteDto[] }> = ({ shuttleR
{/* Akşam Servisleri */} {/* Akşam Servisleri */}
<div> <div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2"> <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center gap-2">
🌆 Akşam Servisleri 🌆 {translate('::App.Platform.Intranet.Widgets.ShuttleRoute.Evening')}
</h3> </h3>
<div className="space-y-2"> <div className="space-y-2">
{eveningShuttles.slice(0, 2).map((shuttle) => ( {eveningShuttles.slice(0, 2).map((shuttle) => (
@ -97,7 +99,7 @@ const ShuttleRoute: React.FC<{ shuttleRoutes: ShuttleRouteDto[] }> = ({ shuttleR
: 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300' : 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300'
}`} }`}
> >
{shuttle.available} yer {shuttle.available} {translate('::App.Platform.Intranet.Widgets.ShuttleRoute.Seat')}
</span> </span>
</div> </div>
</div> </div>

View file

@ -1,15 +1,17 @@
import React from 'react' import React from 'react'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { EmployeeDto } from '@/proxy/intranet/models' import { EmployeeDto } from '@/proxy/intranet/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
const TodayBirthdays: React.FC<{ employees: EmployeeDto[] }> = ({ employees }) => { const TodayBirthdays: React.FC<{ employees: EmployeeDto[] }> = ({ employees }) => {
const today = dayjs() const today = dayjs()
const { translate } = useLocalization();
return ( return (
<div className="bg-gradient-to-br from-pink-50 to-purple-50 dark:from-pink-900/20 dark:to-purple-900/20 rounded-lg shadow-sm border border-pink-200 dark:border-pink-800"> <div className="bg-gradient-to-br from-pink-50 to-purple-50 dark:from-pink-900/20 dark:to-purple-900/20 rounded-lg shadow-sm border border-pink-200 dark:border-pink-800">
<div className="p-4 border-b border-pink-200 dark:border-pink-700"> <div className="p-4 border-b border-pink-200 dark:border-pink-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
🎂 Bugün Doğanlar 🎂 {translate('::App.Platform.Intranet.Widgets.TodayBirthdays.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
@ -30,10 +32,10 @@ const TodayBirthdays: React.FC<{ employees: EmployeeDto[] }> = ({ employees }) =
{birthday.name} {birthday.name}
</p> </p>
<p className="text-xs text-gray-600 dark:text-gray-400"> <p className="text-xs text-gray-600 dark:text-gray-400">
{today.diff(dayjs(birthday.birthDate), 'year')} yaşında 🎉 {translate('::App.Platform.Intranet.Widgets.TodayBirthdays.Age', { age: today.diff(dayjs(birthday.birthDate), 'year') })} 🎉
</p> </p>
<p className="text-xs text-gray-500 dark:text-gray-500 mt-1"> <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">
{birthday.department?.name || 'Genel'} {birthday.department?.name || translate('::App.Platform.Intranet.Widgets.TodayBirthdays.General')}
</p> </p>
</div> </div>
</div> </div>
@ -41,7 +43,7 @@ const TodayBirthdays: React.FC<{ employees: EmployeeDto[] }> = ({ employees }) =
</div> </div>
) : ( ) : (
<p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4"> <p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
Bugün doğan yok {translate('::App.Platform.Intranet.Widgets.TodayBirthdays.NoBirthday')}
</p> </p>
)} )}
</div> </div>

View file

@ -4,9 +4,11 @@ import dayjs from 'dayjs'
import { EventDto } from '@/proxy/intranet/models' import { EventDto } from '@/proxy/intranet/models'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
const UpcomingEvents: React.FC<{ events: EventDto[] }> = ({ events }) => { const UpcomingEvents: React.FC<{ events: EventDto[] }> = ({ events }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
const upcomingEvents = events.filter( const upcomingEvents = events.filter(
(event) => (event) =>
@ -20,7 +22,7 @@ const UpcomingEvents: React.FC<{ events: EventDto[] }> = ({ events }) => {
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaCalendarAlt className="w-5 h-5" /> <FaCalendarAlt className="w-5 h-5" />
Yaklaşan Etkinlikler {translate('::App.Platform.Intranet.Widgets.UpcomingEvents.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
@ -38,7 +40,7 @@ const UpcomingEvents: React.FC<{ events: EventDto[] }> = ({ events }) => {
)) ))
) : ( ) : (
<p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4"> <p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
Yaklaşan etkinlik yok {translate('::App.Platform.Intranet.Widgets.UpcomingEvents.NoEvent')}
</p> </p>
)} )}
</div> </div>

View file

@ -3,16 +3,18 @@ import { FaGraduationCap } from 'react-icons/fa'
import { TrainingDto } from '@/proxy/intranet/models' import { TrainingDto } from '@/proxy/intranet/models'
import { currentLocalDate } from '@/utils/dateUtils' import { currentLocalDate } from '@/utils/dateUtils'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { useLocalization } from '@/utils/hooks/useLocalization'
const UpcomingTrainings: React.FC<{ trainings: TrainingDto[] }> = ({ trainings }) => { const UpcomingTrainings: React.FC<{ trainings: TrainingDto[] }> = ({ trainings }) => {
const currentLocale = useLocale() const currentLocale = useLocale()
const { translate } = useLocalization();
return ( return (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700"> <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaGraduationCap className="w-5 h-5" /> <FaGraduationCap className="w-5 h-5" />
Yaklaşan Eğitimler {translate('::App.Platform.Intranet.Widgets.UpcomingTrainings.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
@ -43,7 +45,7 @@ const UpcomingTrainings: React.FC<{ trainings: TrainingDto[] }> = ({ trainings }
))} ))}
{trainings.filter((t) => t.status === 'upcoming').length === 0 && ( {trainings.filter((t) => t.status === 'upcoming').length === 0 && (
<p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4"> <p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
Yaklaşan eğitim yok {translate('::App.Platform.Intranet.Widgets.UpcomingTrainings.NoTraining')}
</p> </p>
)} )}
</div> </div>

View file

@ -2,15 +2,17 @@ import React from 'react'
import { FaUser, FaUserCheck, FaUserClock } from 'react-icons/fa' import { FaUser, FaUserCheck, FaUserClock } from 'react-icons/fa'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { VisitorDto } from '@/proxy/intranet/models' import { VisitorDto } from '@/proxy/intranet/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => { const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => {
const { translate } = useLocalization();
const getStatusIcon = (status: string) => { const getStatusIcon = (status: string) => {
switch (status) { switch (status) {
case 'Giriş': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Entry', 'Giriş'):
return <FaUserCheck className="w-4 h-4 text-green-600" /> return <FaUserCheck className="w-4 h-4 text-green-600" />
case ıkış': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Exit', ıkış'):
return <FaUser className="w-4 h-4 text-gray-600" /> return <FaUser className="w-4 h-4 text-gray-600" />
case 'Planlandı': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Planned', 'Planlandı'):
return <FaUserClock className="w-4 h-4 text-blue-600" /> return <FaUserClock className="w-4 h-4 text-blue-600" />
default: default:
return <FaUser className="w-4 h-4 text-gray-600" /> return <FaUser className="w-4 h-4 text-gray-600" />
@ -19,14 +21,14 @@ const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => {
const getStatusText = (status: string) => { const getStatusText = (status: string) => {
switch (status) { switch (status) {
case 'Giriş': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Entry', 'Giriş'):
return 'Giriş Yaptı' return translate('::App.Platform.Intranet.Widgets.Visitors.StatusText.Entry')
case ıkış': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Exit', ıkış'):
return ıkış Yaptı' return translate('::App.Platform.Intranet.Widgets.Visitors.StatusText.Exit')
case 'Planlandı': case translate('::App.Platform.Intranet.Widgets.Visitors.Status.Planned', 'Planlandı'):
return 'Planlandı' return translate('::App.Platform.Intranet.Widgets.Visitors.StatusText.Planned')
default: default:
return 'Bilinmiyor' return translate('::App.Platform.Intranet.Widgets.Visitors.StatusText.Unknown')
} }
} }
@ -48,7 +50,7 @@ const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => {
<div className="p-4 border-b border-gray-200 dark:border-gray-700"> <div className="p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<FaUser className="w-5 h-5" /> <FaUser className="w-5 h-5" />
Bugünkü Ziyaretçiler {translate('::App.Platform.Intranet.Widgets.Visitors.Title')}
</h2> </h2>
</div> </div>
<div className="p-4 space-y-3"> <div className="p-4 space-y-3">
@ -90,7 +92,7 @@ const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => {
</div> </div>
{visitor.employee && ( {visitor.employee && (
<p className="text-xs text-gray-500 dark:text-gray-500 mt-1"> <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">
Karşılayan: {visitor.employee.name} {translate('::App.Platform.Intranet.Widgets.Visitors.Host')}: {visitor.employee.name}
</p> </p>
)} )}
</div> </div>
@ -99,7 +101,7 @@ const Visitors: React.FC<{ visitors: VisitorDto[] }> = ({ visitors }) => {
)) ))
) : ( ) : (
<p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4"> <p className="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
Bugün ziyaretçi yok {translate('::App.Platform.Intranet.Widgets.Visitors.NoVisitor')}
</p> </p>
)} )}
</div> </div>