Genel düzenlemeler

This commit is contained in:
Sedat ÖZTÜRK 2025-09-15 12:11:50 +03:00
parent b009b520e1
commit 795ad3d00c
9 changed files with 5372 additions and 583 deletions

View file

@ -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');
})); }));

File diff suppressed because it is too large Load diff

View file

@ -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>
) )
} }

View file

@ -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> </>
) )
} }

View file

@ -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'

View file

@ -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 ık</p> <p className="text-xs sm:text-sm font-medium text-gray-600">Katılıma ı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)) && (

View file

@ -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>
) )
} }

View file

@ -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}

View file

@ -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
} }