Blog sistemindeki güncellemeler4
This commit is contained in:
parent
d59d1009e7
commit
3086927146
13 changed files with 396 additions and 135 deletions
File diff suppressed because one or more lines are too long
|
|
@ -38,7 +38,7 @@ const Header: React.FC = () => {
|
||||||
{ name: t("nav.products"), path: "/products", icon: Package },
|
{ name: t("nav.products"), path: "/products", icon: Package },
|
||||||
{ name: t("nav.services"), path: "/services", icon: Briefcase },
|
{ name: t("nav.services"), path: "/services", icon: Briefcase },
|
||||||
{ name: t("nav.blog"), path: "/blog", icon: BookOpen },
|
{ name: t("nav.blog"), path: "/blog", icon: BookOpen },
|
||||||
{ name: t("nav.forum") || "Forum", path: "/forum", icon: MessageSquare, protected: true },
|
{ name: t("nav.forum"), path: "/forum", icon: MessageSquare, protected: true },
|
||||||
{ name: t("nav.contact"), path: "/contact", icon: Phone },
|
{ name: t("nav.contact"), path: "/contact", icon: Phone },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -11,7 +11,7 @@ const About: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div className="absolute inset-0 opacity-20" style={{
|
<div className="absolute inset-0 opacity-20" style={{
|
||||||
backgroundImage: 'url("https://images.pexels.com/photos/3183183/pexels-photo-3183183.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
backgroundImage: 'url("https://images.pexels.com/photos/3183183/pexels-photo-3183183.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,12 @@ const Blog = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-20"
|
className="absolute inset-0 opacity-20"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage:
|
backgroundImage:
|
||||||
'url("https://images.pexels.com/photos/3183160/pexels-photo-3183160.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
'url("https://images.pexels.com/photos/3183164/pexels-photo-3183164.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ const BlogDetail: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="prose max-w-none text-gray-800" dangerouslySetInnerHTML={{ __html: blogPost.content || "" }} />
|
<div className="prose max-w-none text-gray-800" dangerouslySetInnerHTML={{ __html: t(blogPost.content!!) || "" }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const Contact: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-20"
|
className="absolute inset-0 opacity-20"
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const Forum: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-20"
|
className="absolute inset-0 opacity-20"
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ const Products: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-20"
|
className="absolute inset-0 opacity-20"
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ const Services: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="relative bg-blue-900 text-white py-24">
|
<div className="relative bg-blue-900 text-white py-12">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-20"
|
className="absolute inset-0 opacity-20"
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ class AuthService {
|
||||||
formData.append('grant_type', data.grant_type || 'password');
|
formData.append('grant_type', data.grant_type || 'password');
|
||||||
formData.append('scope', data.scope || 'offline_access Platform');
|
formData.append('scope', data.scope || 'offline_access Platform');
|
||||||
formData.append('client_id', data.client_id || 'Platform_App');
|
formData.append('client_id', data.client_id || 'Platform_App');
|
||||||
// Client secret kaldırıldı - public client olarak çalışıyor
|
|
||||||
|
|
||||||
const response = await apiClient.post<LoginResponse>('/connect/token', formData, {
|
const response = await apiClient.post<LoginResponse>('/connect/token', formData, {
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
// API Base URL
|
// API Base URL
|
||||||
export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:44328';
|
export const API_BASE_URL = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
// Axios instance
|
// Axios instance
|
||||||
export const apiClient = axios.create({
|
export const apiClient = axios.create({
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import { CheckBox } from 'devextreme-react'
|
||||||
import { Checkbox } from '@/components/ui'
|
import { Checkbox } from '@/components/ui'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
import { ConfirmDialog } from '@/components/shared'
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
title: Yup.string().required(),
|
title: Yup.string().required(),
|
||||||
|
|
@ -87,7 +88,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
Veriler yüklenirken hata oluştu
|
{translate('::Error:Loading')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -113,7 +114,7 @@ const BlogManagement = () => {
|
||||||
await blogService.deletePost(id)
|
await blogService.deletePost(id)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Blog yazısı silindi
|
{translate('::KayitSilindi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -123,7 +124,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
Silme işlemi başarısız
|
{translate('::Error:Deleting')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -149,7 +150,7 @@ const BlogManagement = () => {
|
||||||
await blogService.updatePost(editingPost.id, data)
|
await blogService.updatePost(editingPost.id, data)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Blog yazısı güncellendi
|
{translate('::KayitGuncellendi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -159,7 +160,7 @@ const BlogManagement = () => {
|
||||||
await blogService.createPost(data)
|
await blogService.createPost(data)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Blog yazısı oluşturuldu
|
{translate('::KayitEklendi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -172,7 +173,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
İşlem başarısız
|
{translate('::IslemBasarisiz')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -189,7 +190,7 @@ const BlogManagement = () => {
|
||||||
await blogService.unpublishPost(post.id)
|
await blogService.unpublishPost(post.id)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Yayından kaldırıldı
|
{translate('::YayinKaldirildi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -199,7 +200,7 @@ const BlogManagement = () => {
|
||||||
await blogService.publishPost(post.id)
|
await blogService.publishPost(post.id)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Yayınlandı
|
{translate('::Yayinlandi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -210,7 +211,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
İşlem başarısız
|
{translate('::IslemBasarisiz')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -236,7 +237,7 @@ const BlogManagement = () => {
|
||||||
await blogService.deleteCategory(id)
|
await blogService.deleteCategory(id)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Kategori silindi
|
{translate('::KayitSilindi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -246,7 +247,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
Silme işlemi başarısız
|
{translate('::IslemBasarisiz')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -270,7 +271,7 @@ const BlogManagement = () => {
|
||||||
await blogService.updateCategory(editingCategory.id, data)
|
await blogService.updateCategory(editingCategory.id, data)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Kategori güncellendi
|
{translate('::KayitGuncellendi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -280,7 +281,7 @@ const BlogManagement = () => {
|
||||||
await blogService.createCategory(data)
|
await blogService.createCategory(data)
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Başarılı" type="success">
|
<Notification title="Başarılı" type="success">
|
||||||
Kategori oluşturuldu
|
{translate('::KayitEklendi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -293,7 +294,7 @@ const BlogManagement = () => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Hata" type="danger">
|
<Notification title="Hata" type="danger">
|
||||||
İşlem başarısız
|
{translate('::IslemBasarisiz')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-center',
|
placement: 'top-center',
|
||||||
|
|
@ -344,6 +345,17 @@ const BlogManagement = () => {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [confirmDeletePost, setConfirmDeletePost] = useState<BlogPost | null>(null)
|
||||||
|
const [confirmDeleteCategory, setConfirmDeleteCategory] = useState<BlogCategory | null>(null)
|
||||||
|
|
||||||
|
const askDeletePost = (post: BlogPost) => {
|
||||||
|
setConfirmDeletePost(post)
|
||||||
|
}
|
||||||
|
|
||||||
|
const askDeleteCategory = (category: BlogCategory) => {
|
||||||
|
setConfirmDeleteCategory(category)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet
|
<Helmet
|
||||||
|
|
@ -352,37 +364,43 @@ const BlogManagement = () => {
|
||||||
defaultTitle="Kurs Platform"
|
defaultTitle="Kurs Platform"
|
||||||
></Helmet>
|
></Helmet>
|
||||||
<Card>
|
<Card>
|
||||||
<div className="mb-4">
|
<div className="flex gap-2 border-b">
|
||||||
<div className="flex gap-4 border-b">
|
<button
|
||||||
<button
|
className={`p-2 rounded-t-md transition ${
|
||||||
className={`pb-2 px-1 ${activeTab === 'posts' ? 'border-b-2 border-blue-600 text-blue-600' : 'text-gray-600'}`}
|
activeTab === 'posts'
|
||||||
onClick={() => setActiveTab('posts')}
|
? 'bg-blue-100 text-blue-600 font-bold'
|
||||||
>
|
: 'text-gray-600 hover:bg-gray-100 font-semibold'
|
||||||
<b>Blog Yazıları</b>
|
}`}
|
||||||
</button>
|
onClick={() => setActiveTab('posts')}
|
||||||
<button
|
>
|
||||||
className={`pb-2 px-1 ${activeTab === 'categories' ? 'border-b-2 border-blue-600 text-blue-600' : 'text-gray-600'}`}
|
{translate('::blog.posts.title')}
|
||||||
onClick={() => setActiveTab('categories')}
|
</button>
|
||||||
>
|
<button
|
||||||
<b>Kategoriler</b>
|
className={`p-2 rounded-t-md transition ${
|
||||||
</button>
|
activeTab === 'categories'
|
||||||
</div>
|
? 'bg-blue-100 text-blue-600 font-bold'
|
||||||
|
: 'text-gray-600 hover:bg-gray-100 font-semibold'
|
||||||
|
}`}
|
||||||
|
onClick={() => setActiveTab('categories')}
|
||||||
|
>
|
||||||
|
{translate('::blog.posts.categories')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{activeTab === 'posts' ? (
|
{activeTab === 'posts' ? (
|
||||||
<Table compact>
|
<Table compact>
|
||||||
<THead>
|
<THead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Başlık</Th>
|
<Th>{translate('::blog.posts.post.title')}</Th>
|
||||||
<Th>Slug</Th>
|
<Th>{translate('::blog.posts.post.slug')}</Th>
|
||||||
<Th>Kategori</Th>
|
<Th>{translate('::blog.posts.post.category')}</Th>
|
||||||
<Th>Yazar</Th>
|
<Th>{translate('::blog.posts.post.author')}</Th>
|
||||||
<Th>Yayın Tarihi</Th>
|
<Th>{translate('::blog.posts.post.publishDate')}</Th>
|
||||||
<Th>Durum</Th>
|
<Th>{translate('::blog.posts.post.status')}</Th>
|
||||||
<Th>
|
<Th>
|
||||||
{' '}
|
{' '}
|
||||||
<Button variant="solid" size="xs" icon={<HiPlus />} onClick={handleCreate}>
|
<Button variant="solid" size="xs" icon={<HiPlus />} onClick={handleCreate}>
|
||||||
Yeni
|
{translate('::New')}
|
||||||
</Button>
|
</Button>
|
||||||
</Th>
|
</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
|
|
@ -391,7 +409,7 @@ const BlogManagement = () => {
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td colSpan={7} className="text-center">
|
<Td colSpan={7} className="text-center">
|
||||||
Yükleniyor...
|
{translate('::Loading')}
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -407,17 +425,17 @@ const BlogManagement = () => {
|
||||||
: '-'}
|
: '-'}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<Switcher checked={post.isPublished} onChange={() => handlePublish(post)} />
|
<Switcher className="switcher-sm" checked={post.isPublished} onChange={() => handlePublish(post)} />
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Button size="sm" icon={<HiPencil />} onClick={() => handleEdit(post)} />
|
<Button size="xs" icon={<HiPencil />} onClick={() => handleEdit(post)} />
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="xs"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="red-600"
|
color="red-600"
|
||||||
icon={<HiTrash />}
|
icon={<HiTrash />}
|
||||||
onClick={() => handleDelete(post.id)}
|
onClick={() => askDeletePost(post)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
|
|
@ -430,11 +448,11 @@ const BlogManagement = () => {
|
||||||
<Table compact>
|
<Table compact>
|
||||||
<THead>
|
<THead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>İsim</Th>
|
<Th>{translate('::blog.posts.categories.name')}</Th>
|
||||||
<Th>Slug</Th>
|
<Th>{translate('::blog.posts.categories.slug')}</Th>
|
||||||
<Th>Açıklama</Th>
|
<Th>{translate('::blog.posts.categories.description')}</Th>
|
||||||
<Th>Yazı Sayısı</Th>
|
<Th>{translate('::blog.posts.categories.count')}</Th>
|
||||||
<Th>Durum</Th>
|
<Th>{translate('::blog.posts.categories.status')}</Th>
|
||||||
<Th>
|
<Th>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
|
|
@ -442,7 +460,7 @@ const BlogManagement = () => {
|
||||||
icon={<HiPlus />}
|
icon={<HiPlus />}
|
||||||
onClick={handleCreateCategory}
|
onClick={handleCreateCategory}
|
||||||
>
|
>
|
||||||
Yeni
|
{translate('::New')}
|
||||||
</Button>
|
</Button>
|
||||||
</Th>
|
</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
|
|
@ -451,7 +469,7 @@ const BlogManagement = () => {
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td colSpan={5} className="text-center">
|
<Td colSpan={5} className="text-center">
|
||||||
Yükleniyor...
|
{translate('::Loading')}
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -475,16 +493,16 @@ const BlogManagement = () => {
|
||||||
<Td>
|
<Td>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="xs"
|
||||||
icon={<HiPencil />}
|
icon={<HiPencil />}
|
||||||
onClick={() => handleEditCategory(category)}
|
onClick={() => handleEditCategory(category)}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="xs"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="red-600"
|
color="red-600"
|
||||||
icon={<HiTrash />}
|
icon={<HiTrash />}
|
||||||
onClick={() => handleDeleteCategory(category.id)}
|
onClick={() => askDeleteCategory(category)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
|
|
@ -503,7 +521,9 @@ const BlogManagement = () => {
|
||||||
onRequestClose={() => setModalVisible(false)}
|
onRequestClose={() => setModalVisible(false)}
|
||||||
width={1000}
|
width={1000}
|
||||||
>
|
>
|
||||||
<h5 className="mb-4">{editingPost ? 'Blog Yazısını Düzenle' : 'Yeni Blog Yazısı'}</h5>
|
<h5 className="mb-4">
|
||||||
|
{editingPost ? translate('::blog.posts.edittitle') : translate('::blog.posts.newtitle')}
|
||||||
|
</h5>
|
||||||
|
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
|
|
@ -516,22 +536,16 @@ const BlogManagement = () => {
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="Başlık"
|
label={translate('::blog.posts.post.title')}
|
||||||
invalid={errors.title && touched.title}
|
invalid={errors.title && touched.title}
|
||||||
errorMessage={errors.title}
|
errorMessage={errors.title}
|
||||||
>
|
>
|
||||||
<Field
|
<Field type="text" name="title" component={Input} autoFocus={true} />
|
||||||
type="text"
|
|
||||||
name="title"
|
|
||||||
placeholder="Blog başlığı"
|
|
||||||
component={Input}
|
|
||||||
autoFocus={true}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="Slug"
|
label={translate('::blog.posts.post.slug')}
|
||||||
invalid={errors.title && touched.title}
|
invalid={errors.title && touched.title}
|
||||||
errorMessage={errors.title}
|
errorMessage={errors.title}
|
||||||
>
|
>
|
||||||
|
|
@ -540,22 +554,16 @@ const BlogManagement = () => {
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="Özet"
|
label={translate('::blog.posts.post.summary')}
|
||||||
invalid={errors.summary && touched.summary}
|
invalid={errors.summary && touched.summary}
|
||||||
errorMessage={errors.summary}
|
errorMessage={errors.summary}
|
||||||
>
|
>
|
||||||
<Field
|
<Field name="summary" component={Input} />
|
||||||
name="summary"
|
|
||||||
placeholder="Kısa açıklama"
|
|
||||||
component={Input}
|
|
||||||
textArea={true}
|
|
||||||
rows={3}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="Kategori"
|
label={translate('::blog.posts.post.category')}
|
||||||
invalid={errors.categoryId && touched.categoryId}
|
invalid={errors.categoryId && touched.categoryId}
|
||||||
errorMessage={errors.categoryId}
|
errorMessage={errors.categoryId}
|
||||||
>
|
>
|
||||||
|
|
@ -573,26 +581,21 @@ const BlogManagement = () => {
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem label="Etiketler - Virgül ile ayırarak yazınız">
|
<FormItem label={translate('::blog.posts.post.tags')}>
|
||||||
<Field
|
<Field
|
||||||
type="text"
|
type="text"
|
||||||
name="tags"
|
name="tags"
|
||||||
placeholder="örn: react, javascript, web"
|
placeholder="react, javascript, web"
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem label="Kapak Görseli">
|
<FormItem label={translate('::blog.posts.post.image')}>
|
||||||
<Field
|
<Field type="text" name="coverImage" component={Input} />
|
||||||
type="text"
|
|
||||||
name="coverImage"
|
|
||||||
placeholder="Görsel URL'si"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="İçerik"
|
label={translate('::blog.posts.post.content')}
|
||||||
asterisk
|
asterisk
|
||||||
invalid={!!errors.content}
|
invalid={!!errors.content}
|
||||||
errorMessage={errors.content}
|
errorMessage={errors.content}
|
||||||
|
|
@ -606,7 +609,7 @@ const BlogManagement = () => {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Durum"
|
label={translate('::blog.posts.post.status')}
|
||||||
invalid={errors.isPublished && touched.isPublished}
|
invalid={errors.isPublished && touched.isPublished}
|
||||||
errorMessage={errors.isPublished}
|
errorMessage={errors.isPublished}
|
||||||
>
|
>
|
||||||
|
|
@ -616,10 +619,12 @@ const BlogManagement = () => {
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Button variant="solid" type="submit" loading={isSubmitting}>
|
<Button variant="solid" type="submit" loading={isSubmitting}>
|
||||||
{editingPost ? 'Güncelle' : 'Oluştur'}
|
{editingPost
|
||||||
|
? translate('::blog.posts.post.update')
|
||||||
|
: translate('::blog.posts.post.create')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="plain" onClick={() => setModalVisible(false)}>
|
<Button variant="plain" onClick={() => setModalVisible(false)}>
|
||||||
İptal
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -636,7 +641,11 @@ const BlogManagement = () => {
|
||||||
onRequestClose={() => setCategoryModalVisible(false)}
|
onRequestClose={() => setCategoryModalVisible(false)}
|
||||||
width={600}
|
width={600}
|
||||||
>
|
>
|
||||||
<h5 className="mb-4">{editingCategory ? 'Kategoriyi Düzenle' : 'Yeni Kategori'}</h5>
|
<h5 className="mb-4">
|
||||||
|
{editingCategory
|
||||||
|
? translate('::blog.posts.categories.edittitle')
|
||||||
|
: translate('::blog.posts.categories.newtitle')}
|
||||||
|
</h5>
|
||||||
|
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialCategoryValues}
|
initialValues={initialCategoryValues}
|
||||||
|
|
@ -649,26 +658,20 @@ const BlogManagement = () => {
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="İsim"
|
label={translate('::blog.posts.categories.name')}
|
||||||
invalid={errors.name && touched.name}
|
invalid={errors.name && touched.name}
|
||||||
errorMessage={errors.name}
|
errorMessage={errors.name}
|
||||||
>
|
>
|
||||||
<Field
|
<Field autoFocus={true} type="text" name="name" component={Input} />
|
||||||
autoFocus={true}
|
|
||||||
type="text"
|
|
||||||
name="name"
|
|
||||||
placeholder="Kategori ismi"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
asterisk
|
asterisk
|
||||||
label="Slug"
|
label={translate('::blog.posts.categories.slug')}
|
||||||
invalid={errors.slug && touched.slug}
|
invalid={errors.slug && touched.slug}
|
||||||
errorMessage={errors.slug}
|
errorMessage={errors.slug}
|
||||||
>
|
>
|
||||||
<Field type="text" name="slug" placeholder="kategori-slug" component={Input} />
|
<Field type="text" name="slug" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -677,24 +680,21 @@ const BlogManagement = () => {
|
||||||
errorMessage={errors.description}
|
errorMessage={errors.description}
|
||||||
>
|
>
|
||||||
<Field
|
<Field
|
||||||
name="description"
|
name={translate('::blog.posts.categories.description')}
|
||||||
placeholder="Kategori açıklaması"
|
|
||||||
component={Input}
|
component={Input}
|
||||||
textArea={true}
|
|
||||||
rows={3}
|
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem label="İkon (Emoji)">
|
<FormItem label={translate('::blog.posts.categories.icon')}>
|
||||||
<Field type="text" name="icon" placeholder="📚" component={Input} />
|
<Field type="text" name="icon" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem label="Sıralama">
|
<FormItem label={translate('::blog.posts.categories.order')}>
|
||||||
<Field type="number" name="displayOrder" placeholder="0" component={Input} />
|
<Field type="number" name="displayOrder" placeholder="0" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Durum"
|
label={translate('::blog.posts.categories.status')}
|
||||||
invalid={errors.isActive && touched.isActive}
|
invalid={errors.isActive && touched.isActive}
|
||||||
errorMessage={errors.isActive}
|
errorMessage={errors.isActive}
|
||||||
>
|
>
|
||||||
|
|
@ -704,10 +704,12 @@ const BlogManagement = () => {
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Button variant="solid" type="submit" loading={isSubmitting}>
|
<Button variant="solid" type="submit" loading={isSubmitting}>
|
||||||
{editingCategory ? 'Güncelle' : 'Oluştur'}
|
{editingCategory
|
||||||
|
? translate('::blog.posts.categories.update')
|
||||||
|
: translate('::blog.posts.categories.create')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="plain" onClick={() => setCategoryModalVisible(false)}>
|
<Button variant="plain" onClick={() => setCategoryModalVisible(false)}>
|
||||||
İptal
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -716,6 +718,50 @@ const BlogManagement = () => {
|
||||||
)}
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
{/* Post Silme Onayı */}
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={!!confirmDeletePost}
|
||||||
|
type="danger"
|
||||||
|
title={translate('::DeleteConfirmation')}
|
||||||
|
confirmText={translate('::Delete')}
|
||||||
|
cancelText={translate('::Cancel')}
|
||||||
|
confirmButtonColor="red-600"
|
||||||
|
onCancel={() => setConfirmDeletePost(null)}
|
||||||
|
onConfirm={async () => {
|
||||||
|
if (confirmDeletePost) {
|
||||||
|
await handleDelete(confirmDeletePost.id)
|
||||||
|
setConfirmDeletePost(null)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<span className="font-semibold">{confirmDeletePost?.title}</span>{' '}
|
||||||
|
{translate('::DeleteConfirmation')}
|
||||||
|
</p>
|
||||||
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
{/* Kategori Silme Onayı */}
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={!!confirmDeleteCategory}
|
||||||
|
type="danger"
|
||||||
|
title={translate('::DeleteConfirmation')}
|
||||||
|
confirmText={translate('::Delete')}
|
||||||
|
cancelText={translate('::Cancel')}
|
||||||
|
confirmButtonColor="red-600"
|
||||||
|
onCancel={() => setConfirmDeleteCategory(null)}
|
||||||
|
onConfirm={async () => {
|
||||||
|
if (confirmDeleteCategory) {
|
||||||
|
await handleDeleteCategory(confirmDeleteCategory.id)
|
||||||
|
setConfirmDeleteCategory(null)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<span className="font-semibold">{confirmDeleteCategory?.name}</span>{' '}
|
||||||
|
{translate('::DeleteConfirmation')}
|
||||||
|
</p>
|
||||||
|
</ConfirmDialog>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue