Blog Türkçe İngilizce Content
This commit is contained in:
parent
a663cc0079
commit
d0d255f41e
18 changed files with 112 additions and 70 deletions
|
|
@ -8,7 +8,8 @@ namespace Kurs.Platform.Blog
|
|||
{
|
||||
public string Title { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ContentTr { get; set; }
|
||||
public string ContentEn { get; set; }
|
||||
public string Summary { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
|
||||
|
|
@ -44,7 +45,8 @@ namespace Kurs.Platform.Blog
|
|||
{
|
||||
public string Title { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ContentTr { get; set; }
|
||||
public string ContentEn { get; set; }
|
||||
public string Summary { get; set; }
|
||||
public string ReadTime { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
|
|
@ -65,7 +67,8 @@ namespace Kurs.Platform.Blog
|
|||
public string Summary { get; set; }
|
||||
public string ReadTime { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ContentTr { get; set; }
|
||||
public string ContentEn { get; set; }
|
||||
|
||||
public BlogCategoryDto Category { get; set; }
|
||||
public AuthorDto Author { get; set; }
|
||||
|
|
|
|||
|
|
@ -126,7 +126,8 @@ namespace Kurs.Platform.Blog
|
|||
GuidGenerator.Create(),
|
||||
input.Title,
|
||||
input.Slug,
|
||||
input.Content,
|
||||
input.ContentTr,
|
||||
input.ContentEn,
|
||||
input.Summary,
|
||||
input.ReadTime,
|
||||
input.CoverImage,
|
||||
|
|
@ -160,7 +161,8 @@ namespace Kurs.Platform.Blog
|
|||
post.Slug = input.Slug;
|
||||
post.Summary = input.Summary;
|
||||
post.CoverImage = input.CoverImage;
|
||||
post.Content = input.Content;
|
||||
post.ContentTr = input.ContentTr;
|
||||
post.ContentEn = input.ContentEn;
|
||||
|
||||
if (input.IsPublished) post.Publish(); else post.Unpublish();
|
||||
|
||||
|
|
|
|||
|
|
@ -582,7 +582,8 @@ public class PlatformDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
item.Id,
|
||||
item.Title,
|
||||
item.Slug,
|
||||
item.Content,
|
||||
item.ContentTr,
|
||||
item.ContentEn,
|
||||
item.Summary,
|
||||
item.ReadTime,
|
||||
item.CoverImage,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -215,7 +215,8 @@ public class BlogPostSeedDto
|
|||
public Guid Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ContentTr { get; set; }
|
||||
public string ContentEn { get; set; }
|
||||
public string ReadTime { get; set; }
|
||||
public string Summary { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ namespace Kurs.Platform.Blog
|
|||
|
||||
public string Title { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ContentTr { get; set; }
|
||||
public string ContentEn { get; set; }
|
||||
public string Summary { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
public string ReadTime { get; set; }
|
||||
|
|
@ -35,7 +36,8 @@ namespace Kurs.Platform.Blog
|
|||
Guid id,
|
||||
string title,
|
||||
string slug,
|
||||
string content,
|
||||
string contentTr,
|
||||
string contentEn,
|
||||
string summary,
|
||||
string readTime,
|
||||
string coverImage,
|
||||
|
|
@ -45,7 +47,8 @@ namespace Kurs.Platform.Blog
|
|||
{
|
||||
Title = title;
|
||||
Slug = slug;
|
||||
Content = content;
|
||||
ContentTr = contentTr;
|
||||
ContentEn = contentEn;
|
||||
Summary = summary;
|
||||
ReadTime = readTime;
|
||||
CoverImage = coverImage;
|
||||
|
|
|
|||
|
|
@ -415,7 +415,8 @@ public class PlatformDbContext :
|
|||
b.Property(x => x.Title).IsRequired().HasMaxLength(256);
|
||||
b.Property(x => x.Slug).IsRequired().HasMaxLength(256);
|
||||
b.Property(x => x.Summary).IsRequired().HasMaxLength(512);
|
||||
b.Property(x => x.Content).IsRequired();
|
||||
b.Property(x => x.ContentTr).IsRequired();
|
||||
b.Property(x => x.ContentEn).IsRequired();
|
||||
b.Property(x => x.CoverImage).HasMaxLength(512);
|
||||
|
||||
b.HasIndex(x => x.Slug);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ using Volo.Abp.EntityFrameworkCore;
|
|||
namespace Kurs.Platform.Migrations
|
||||
{
|
||||
[DbContext(typeof(PlatformDbContext))]
|
||||
[Migration("20250622112214_AddBlogEntities")]
|
||||
partial class AddBlogEntities
|
||||
[Migration("20250622123512_AddBlog")]
|
||||
partial class AddBlog
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
|
|
@ -746,7 +746,11 @@ namespace Kurs.Platform.Migrations
|
|||
.HasColumnType("nvarchar(40)")
|
||||
.HasColumnName("ConcurrencyStamp");
|
||||
|
||||
b.Property<string>("Content")
|
||||
b.Property<string>("ContentEn")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ContentTr")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||
namespace Kurs.Platform.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBlogEntities : Migration
|
||||
public partial class AddBlog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
|
|
@ -45,7 +45,8 @@ namespace Kurs.Platform.Migrations
|
|||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||
Title = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
||||
Slug = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
||||
Content = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
ContentTr = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
ContentEn = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Summary = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: false),
|
||||
CoverImage = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
|
||||
ReadTime = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
|
|
@ -743,7 +743,11 @@ namespace Kurs.Platform.Migrations
|
|||
.HasColumnType("nvarchar(40)")
|
||||
.HasColumnName("ConcurrencyStamp");
|
||||
|
||||
b.Property<string>("Content")
|
||||
b.Property<string>("ContentEn")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ContentTr")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@ function App() {
|
|||
<Layout>
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/products" element={<Products />} />
|
||||
<Route path="/services" element={<Services />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/blog" element={<Blog />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="/blog/:id" element={<BlogDetail />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Routes>
|
||||
</Layout>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -16,7 +16,7 @@ interface PostData {
|
|||
|
||||
const BlogDetail: React.FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const { t } = useLanguage();
|
||||
const { language, setLanguage, t } = useLanguage();
|
||||
const [blogPost, setBlogPost] = useState<BlogPost | null>(null);
|
||||
const [postData, setPostData] = useState<PostData | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
|
@ -103,7 +103,7 @@ const BlogDetail: React.FC = () => {
|
|||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="prose max-w-none text-gray-800" dangerouslySetInnerHTML={{ __html: t(blogPost.content!!) || "" }} />
|
||||
<div className="prose max-w-none text-gray-800" dangerouslySetInnerHTML={{ __html: language == "tr" ? t(blogPost.contentTr!!) : t(blogPost.contentEn!!) }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ export interface BlogPost {
|
|||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
content?: string;
|
||||
contentTr?: string;
|
||||
contentEn?: string;
|
||||
summary: string;
|
||||
readTime: string;
|
||||
coverImage?: string;
|
||||
|
|
@ -58,7 +59,8 @@ export interface BlogComment {
|
|||
export interface CreateBlogPostRequest {
|
||||
title: string;
|
||||
slug: string;
|
||||
content: string;
|
||||
contentTr: string;
|
||||
contentEn: string;
|
||||
summary: string;
|
||||
categoryId: string;
|
||||
tags: string[];
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
|||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "index.html",
|
||||
"revision": "0.6hosm5icco8"
|
||||
"revision": "0.pd7p0avqcno"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
|
|
|
|||
|
|
@ -63,12 +63,6 @@ const adminRoutes: Routes = [
|
|||
component: lazy(() => import('@/views/blog/BlogManagement')),
|
||||
authority: [],
|
||||
},
|
||||
{
|
||||
key: ROUTES_ENUM.admin.forum.management,
|
||||
path: ROUTES_ENUM.admin.forum.management,
|
||||
component: lazy(() => import('@/views/forum/AdminView')),
|
||||
authority: [],
|
||||
},
|
||||
]
|
||||
|
||||
export { adminRoutes }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ export interface BlogPost {
|
|||
id: string
|
||||
title: string
|
||||
slug: string
|
||||
content?: string
|
||||
contentTr?: string
|
||||
contentEn?: string
|
||||
summary: string
|
||||
coverImage?: string
|
||||
author: {
|
||||
|
|
@ -58,7 +59,8 @@ export interface BlogComment {
|
|||
export interface CreateUpdateBlogPostDto {
|
||||
title: string
|
||||
slug: string
|
||||
content: string
|
||||
contentTr: string
|
||||
contentEn: string
|
||||
summary: string
|
||||
categoryId: string
|
||||
tags: string[]
|
||||
|
|
|
|||
|
|
@ -31,11 +31,14 @@ import THead from '@/components/ui/Table/THead'
|
|||
import TBody from '@/components/ui/Table/TBody'
|
||||
import Td from '@/components/ui/Table/Td'
|
||||
import { SelectBoxOption } from '@/shared/types'
|
||||
import { Checkbox } from '@/components/ui'
|
||||
import { Checkbox, Tabs } from '@/components/ui'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ConfirmDialog } from '@/components/shared'
|
||||
import { useStoreState } from '@/store/store'
|
||||
import TabList from '@/components/ui/Tabs/TabList'
|
||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
||||
import TabContent from '@/components/ui/Tabs/TabContent'
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
title: Yup.string().required(),
|
||||
|
|
@ -84,8 +87,8 @@ const BlogManagement = () => {
|
|||
blogService.getPosts({ pageSize: 100 }),
|
||||
blogService.getCategories(),
|
||||
])
|
||||
setCategories(categoriesData.filter(a=>a.name.startsWith("blog")))
|
||||
setPosts(postsData.items.filter(a=> a.title.startsWith("blog")))
|
||||
setCategories(categoriesData.filter((a) => a.name.startsWith('blog')))
|
||||
setPosts(postsData.items.filter((a) => a.title.startsWith('blog')))
|
||||
} catch (error) {
|
||||
toast.push(
|
||||
<Notification title="Hata" type="danger">
|
||||
|
|
@ -139,7 +142,8 @@ const BlogManagement = () => {
|
|||
const data: CreateUpdateBlogPostDto = {
|
||||
title: values.title,
|
||||
slug: values.slug,
|
||||
content: values.content,
|
||||
contentTr: values.contentTr,
|
||||
contentEn: values.contentEn,
|
||||
summary: values.summary,
|
||||
categoryId: values.categoryId,
|
||||
tags: values.tags ? values.tags.split(',').map((t: string) => t.trim()) : [],
|
||||
|
|
@ -311,7 +315,8 @@ const BlogManagement = () => {
|
|||
title: editingPost.title,
|
||||
slug: editingPost.slug,
|
||||
summary: editingPost.summary,
|
||||
content: editingPost.content,
|
||||
contentTr: editingPost.contentTr,
|
||||
contentEn: editingPost.contentEn,
|
||||
categoryId: editingPost.category.id,
|
||||
tags: editingPost.tags.join(', '),
|
||||
coverImage: editingPost.coverImage || '',
|
||||
|
|
@ -641,19 +646,44 @@ const BlogManagement = () => {
|
|||
<Field type="text" name="coverImage" component={Input} />
|
||||
</FormItem>
|
||||
|
||||
<Tabs defaultValue="tr" variant="pill">
|
||||
<TabList className="flex-wrap border-b mb-4 bg-slate-50 rounded-t">
|
||||
<TabNav value="tr">Türkçe</TabNav>
|
||||
<TabNav value="en">English</TabNav>
|
||||
</TabList>
|
||||
|
||||
<TabContent value="tr">
|
||||
<FormItem
|
||||
label={translate('::blog.posts.post.content')}
|
||||
asterisk
|
||||
invalid={!!errors.content}
|
||||
errorMessage={errors.content}
|
||||
invalid={!!errors.contentTr}
|
||||
errorMessage={errors.contentTr}
|
||||
>
|
||||
<ReactQuill
|
||||
theme="snow"
|
||||
value={values.content}
|
||||
onChange={(val: string) => setFieldValue('content', val)}
|
||||
value={values.contentTr}
|
||||
onChange={(val: string) => setFieldValue('contentTr', val)}
|
||||
style={{ height: '300px', marginBottom: '50px' }}
|
||||
/>
|
||||
</FormItem>
|
||||
</TabContent>
|
||||
|
||||
<TabContent value="en">
|
||||
<FormItem
|
||||
label={translate('::blog.posts.post.content')}
|
||||
asterisk
|
||||
invalid={!!errors.contentEn}
|
||||
errorMessage={errors.contentEn}
|
||||
>
|
||||
<ReactQuill
|
||||
theme="snow"
|
||||
value={values.contentEn}
|
||||
onChange={(val: string) => setFieldValue('contentEn', val)}
|
||||
style={{ height: '300px', marginBottom: '50px' }}
|
||||
/>
|
||||
</FormItem>
|
||||
</TabContent>
|
||||
</Tabs>
|
||||
|
||||
<FormItem
|
||||
label={translate('::blog.posts.post.status')}
|
||||
|
|
|
|||
Loading…
Reference in a new issue