Genel düzenlemeler
This commit is contained in:
parent
b009b520e1
commit
795ad3d00c
9 changed files with 5372 additions and 583 deletions
|
|
@ -67,7 +67,7 @@ if (!self.define) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
define(['./workbox-a959eb95'], (function (workbox) { 'use strict';
|
||||||
|
|
||||||
self.skipWaiting();
|
self.skipWaiting();
|
||||||
workbox.clientsClaim();
|
workbox.clientsClaim();
|
||||||
|
|
@ -81,13 +81,29 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
||||||
"url": "registerSW.js",
|
"url": "registerSW.js",
|
||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "/index.html",
|
||||||
"revision": "0.h9qpsacvko"
|
"revision": "0.g281p2a917g"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), {
|
||||||
allowlist: [/^\/$/],
|
allowlist: [/^\/$/],
|
||||||
denylist: [/^\/api\//]
|
denylist: [/^\/api\//]
|
||||||
}));
|
}));
|
||||||
|
workbox.registerRoute(/\.(?:js|css|html|json)$/, new workbox.NetworkFirst({
|
||||||
|
"cacheName": "static-resources",
|
||||||
|
plugins: [new workbox.ExpirationPlugin({
|
||||||
|
maxEntries: 50,
|
||||||
|
maxAgeSeconds: 86400
|
||||||
|
}), new workbox.CacheableResponsePlugin({
|
||||||
|
statuses: [0, 200]
|
||||||
|
})]
|
||||||
|
}), 'GET');
|
||||||
|
workbox.registerRoute(/\.(?:png|jpg|jpeg|svg|gif|webp|ico)$/, new workbox.CacheFirst({
|
||||||
|
"cacheName": "images",
|
||||||
|
plugins: [new workbox.ExpirationPlugin({
|
||||||
|
maxEntries: 100,
|
||||||
|
maxAgeSeconds: 2592000
|
||||||
|
})]
|
||||||
|
}), 'GET');
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
4784
ui/dev-dist/workbox-a959eb95.js
Normal file
4784
ui/dev-dist/workbox-a959eb95.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -49,12 +49,10 @@ const DeveloperLayout: React.FC<DeveloperLayoutProps> = ({ children }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="flex-1">{children}</div>
|
<div className="flex-1">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ export const Dashboard: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
<>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="flex items-center justify-center min-h-96">
|
<div className="flex items-center justify-center min-h-96">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
|
|
@ -236,7 +236,9 @@ export const Dashboard: React.FC = () => {
|
||||||
<div className="bg-white rounded-xl shadow-md p-6 border border-gray-200">
|
<div className="bg-white rounded-xl shadow-md p-6 border border-gray-200">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-gray-600">{translate('::App.Reports.Dashboard.ActiveCategories')}</p>
|
<p className="text-sm font-medium text-gray-600">
|
||||||
|
{translate('::App.Reports.Dashboard.ActiveCategories')}
|
||||||
|
</p>
|
||||||
<p className="text-2xl font-bold text-gray-900">{categories.length}</p>
|
<p className="text-2xl font-bold text-gray-900">{categories.length}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-emerald-100 p-3 rounded-full">
|
<div className="bg-emerald-100 p-3 rounded-full">
|
||||||
|
|
@ -313,6 +315,6 @@ export const Dashboard: React.FC = () => {
|
||||||
template={generatingTemplate}
|
template={generatingTemplate}
|
||||||
onGenerate={handleReportGeneration}
|
onGenerate={handleReportGeneration}
|
||||||
/>
|
/>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,54 @@
|
||||||
export interface ForumCategory {
|
export interface ForumCategory {
|
||||||
id: string;
|
id: string
|
||||||
name: string;
|
name: string
|
||||||
slug: string;
|
slug: string
|
||||||
description: string;
|
description: string
|
||||||
icon: string;
|
icon: string
|
||||||
displayOrder: number;
|
displayOrder: number
|
||||||
isActive: boolean;
|
isActive: boolean
|
||||||
isLocked: boolean;
|
isLocked: boolean
|
||||||
topicCount: number;
|
topicCount: number
|
||||||
postCount: number;
|
postCount: number
|
||||||
lastPostId?: string;
|
lastPostId?: string
|
||||||
lastPostDate?: string;
|
lastPostDate?: string
|
||||||
lastPostUserId?: string;
|
lastPostUserId?: string
|
||||||
creationTime: string;
|
creationTime: string
|
||||||
tenantId?: string;
|
tenantId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ForumTopic {
|
export interface ForumTopic {
|
||||||
id: string;
|
id: string
|
||||||
title: string;
|
title: string
|
||||||
content: string;
|
content: string
|
||||||
categoryId: string;
|
categoryId: string
|
||||||
authorId: string;
|
authorId: string
|
||||||
authorName: string;
|
authorName: string
|
||||||
viewCount: number;
|
viewCount: number
|
||||||
replyCount: number;
|
replyCount: number
|
||||||
likeCount: number;
|
likeCount: number
|
||||||
isPinned: boolean;
|
isPinned: boolean
|
||||||
isLocked: boolean;
|
isLocked: boolean
|
||||||
isSolved: boolean;
|
isSolved: boolean
|
||||||
lastPostId?: string;
|
lastPostId?: string
|
||||||
lastPostDate?: string;
|
lastPostDate?: string
|
||||||
lastPostUserId?: string;
|
lastPostUserId?: string
|
||||||
lastPostUserName?: string;
|
lastPostUserName?: string
|
||||||
creationTime: string;
|
creationTime: string
|
||||||
tenantId?: string;
|
tenantId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ForumPost {
|
export interface ForumPost {
|
||||||
id: string;
|
id: string
|
||||||
topicId: string;
|
topicId: string
|
||||||
content: string;
|
content: string
|
||||||
authorId: string;
|
authorId: string
|
||||||
authorName: string;
|
authorName: string
|
||||||
likeCount: number;
|
likeCount: number
|
||||||
isAcceptedAnswer: boolean;
|
isAcceptedAnswer: boolean
|
||||||
parentPostId?: string;
|
parentPostId?: string
|
||||||
creationTime: string;
|
creationTime: string
|
||||||
tenantId?: string;
|
tenantId?: string
|
||||||
|
children: ForumPost[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ViewMode = 'forum' | 'admin';
|
export type ViewMode = 'forum' | 'admin'
|
||||||
|
|
|
||||||
|
|
@ -262,8 +262,6 @@ const ClassList: React.FC = () => {
|
||||||
defaultTitle="Sözsoft Kurs Platform"
|
defaultTitle="Sözsoft Kurs Platform"
|
||||||
></Helmet>
|
></Helmet>
|
||||||
<Container>
|
<Container>
|
||||||
{/* Main Content */}
|
|
||||||
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
||||||
{/* Stats Cards */}
|
{/* Stats Cards */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4 sm:gap-6 mb-6 sm:mb-8">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4 sm:gap-6 mb-6 sm:mb-8">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -317,9 +315,7 @@ const ClassList: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-3 sm:ml-4">
|
<div className="ml-3 sm:ml-4">
|
||||||
<p className="text-xs sm:text-sm font-medium text-gray-600">Katılıma Açık</p>
|
<p className="text-xs sm:text-sm font-medium text-gray-600">Katılıma Açık</p>
|
||||||
<p className="text-xl sm:text-2xl font-bold text-gray-900">
|
<p className="text-xl sm:text-2xl font-bold text-gray-900">{widgets().openCount}</p>
|
||||||
{widgets().openCount}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
@ -498,9 +494,7 @@ const ClassList: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
|
||||||
<p className="text-gray-600 text-sm sm:text-base">
|
<p className="text-gray-600 text-sm sm:text-base">{classSession.subject}</p>
|
||||||
{classSession.subject}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
|
||||||
|
|
@ -549,7 +543,6 @@ const ClassList: React.FC = () => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Class Modal (Create/Edit) */}
|
{/* Class Modal (Create/Edit) */}
|
||||||
{(showCreateModal || (showEditModal && classroom)) && (
|
{(showCreateModal || (showEditModal && classroom)) && (
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ export function AdminView({
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
{/* Sidebar Navigation */}
|
{/* Sidebar Navigation */}
|
||||||
<div className="lg:w-64 flex-shrink-0 p-4 bg-gray-50">
|
<div className="lg:w-64 flex-shrink-0 p-4 bg-gray-50">
|
||||||
|
|
@ -175,6 +174,5 @@ export function AdminView({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { FaArrowLeft, FaPlus, FaSpinner, FaSearch } from 'react-icons/fa';
|
import { FaArrowLeft, FaPlus, FaSpinner, FaSearch } from 'react-icons/fa'
|
||||||
import { CreateTopicModal } from './CreateTopicModal'
|
import { CreateTopicModal } from './CreateTopicModal'
|
||||||
import { CreatePostModal } from './CreatePostModal'
|
import { CreatePostModal } from './CreatePostModal'
|
||||||
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
||||||
|
|
@ -238,7 +238,7 @@ export function ForumView({
|
||||||
|
|
||||||
const threadedPosts = buildPostTree(filteredPosts)
|
const threadedPosts = buildPostTree(filteredPosts)
|
||||||
|
|
||||||
function renderPosts(posts: (ForumPost & { children: ForumPost[] })[]) {
|
function renderPosts(posts: ForumPost[]) {
|
||||||
return posts.map((post) => (
|
return posts.map((post) => (
|
||||||
<div key={post.id}>
|
<div key={post.id}>
|
||||||
<ForumPostCard
|
<ForumPostCard
|
||||||
|
|
@ -301,7 +301,6 @@ export function ForumView({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
||||||
{/* Breadcrumb + Actions + Search Row */}
|
{/* Breadcrumb + Actions + Search Row */}
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-4">
|
||||||
{/* Left Side: Breadcrumb */}
|
{/* Left Side: Breadcrumb */}
|
||||||
|
|
@ -377,7 +376,9 @@ export function ForumView({
|
||||||
className="hidden md:flex items-center space-x-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
className="hidden md:flex items-center space-x-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
||||||
>
|
>
|
||||||
<FaSearch className="w-4 h-4 text-gray-400" />
|
<FaSearch className="w-4 h-4 text-gray-400" />
|
||||||
<span className="text-gray-500">{translate('::App.Forum.TopicManagement.Searchtopics')}</span>
|
<span className="text-gray-500">
|
||||||
|
{translate('::App.Forum.TopicManagement.Searchtopics')}
|
||||||
|
</span>
|
||||||
<kbd className="hidden sm:inline-block px-2 py-1 text-xs font-semibold text-gray-500 bg-gray-100 border border-gray-200 rounded">
|
<kbd className="hidden sm:inline-block px-2 py-1 text-xs font-semibold text-gray-500 bg-gray-100 border border-gray-200 rounded">
|
||||||
⌘K
|
⌘K
|
||||||
</kbd>
|
</kbd>
|
||||||
|
|
@ -455,6 +456,7 @@ export function ForumView({
|
||||||
parentPostId: undefined,
|
parentPostId: undefined,
|
||||||
creationTime: selectedTopic.creationTime,
|
creationTime: selectedTopic.creationTime,
|
||||||
tenantId: selectedTopic.tenantId,
|
tenantId: selectedTopic.tenantId,
|
||||||
|
children: [],
|
||||||
}}
|
}}
|
||||||
onLike={handleLike}
|
onLike={handleLike}
|
||||||
onReply={handleReply}
|
onReply={handleReply}
|
||||||
|
|
@ -470,10 +472,7 @@ export function ForumView({
|
||||||
|
|
||||||
{/* Create Topic Modal */}
|
{/* Create Topic Modal */}
|
||||||
{showCreateTopic && (
|
{showCreateTopic && (
|
||||||
<CreateTopicModal
|
<CreateTopicModal onClose={() => setShowCreateTopic(false)} onSubmit={handleCreateTopic} />
|
||||||
onClose={() => setShowCreateTopic(false)}
|
|
||||||
onSubmit={handleCreateTopic}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Create Post Modal */}
|
{/* Create Post Modal */}
|
||||||
|
|
@ -484,7 +483,6 @@ export function ForumView({
|
||||||
parentPostId={replyToPostId!}
|
parentPostId={replyToPostId!}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
|
||||||
<SearchModal
|
<SearchModal
|
||||||
isOpen={isSearchModalOpen}
|
isOpen={isSearchModalOpen}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,23 @@
|
||||||
import { ForumPost } from '@/proxy/forum/forum'
|
import { ForumPost } from '@/proxy/forum/forum'
|
||||||
|
|
||||||
export function buildPostTree(posts: ForumPost[]): (ForumPost & { children: ForumPost[] })[] {
|
export function buildPostTree(posts: ForumPost[]): ForumPost[] {
|
||||||
const postMap = new Map<string, ForumPost & { children: ForumPost[] }>();
|
const postMap = new Map<string, ForumPost>()
|
||||||
|
|
||||||
// 1. Her post için children array'i eklenmiş yeni bir nesne oluştur
|
// 1. Her post için children array'i eklenmiş yeni bir nesne oluştur
|
||||||
posts.forEach((post) => {
|
posts.forEach((post) => {
|
||||||
postMap.set(post.id, { ...post, children: [] });
|
postMap.set(post.id, { ...post, children: [] })
|
||||||
});
|
})
|
||||||
|
|
||||||
const roots: (ForumPost & { children: ForumPost[] })[] = [];
|
const roots: ForumPost[] = []
|
||||||
|
|
||||||
// 2. Her post'un parent'ı varsa ilgili parent'ın children listesine ekle
|
// 2. Her post'un parent'ı varsa ilgili parent'ın children listesine ekle
|
||||||
postMap.forEach((post) => {
|
postMap.forEach((post) => {
|
||||||
if (post.parentPostId && postMap.has(post.parentPostId)) {
|
if (post.parentPostId && postMap.has(post.parentPostId)) {
|
||||||
postMap.get(post.parentPostId)!.children.push(post);
|
postMap.get(post.parentPostId)!.children.push(post)
|
||||||
} else {
|
} else {
|
||||||
roots.push(post);
|
roots.push(post)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return roots;
|
return roots
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue