@armoyu/ui 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/dist/app/Providers.d.ts +6 -0
  2. package/dist/app/Providers.d.ts.map +1 -0
  3. package/dist/app/Providers.js +37 -0
  4. package/dist/app/Providers.js.map +1 -0
  5. package/dist/app/api/proxy/[...path]/route.d.ts +22 -0
  6. package/dist/app/api/proxy/[...path]/route.d.ts.map +1 -0
  7. package/dist/app/api/proxy/[...path]/route.js +97 -0
  8. package/dist/app/api/proxy/[...path]/route.js.map +1 -0
  9. package/dist/app/layout.d.ts.map +1 -1
  10. package/dist/app/layout.js +16 -23
  11. package/dist/app/layout.js.map +1 -1
  12. package/dist/components/RollingNumber.d.ts +6 -6
  13. package/dist/components/RollingNumber.js +23 -23
  14. package/dist/components/RollingNumber.js.map +1 -1
  15. package/dist/components/StatsGrid.d.ts +5 -5
  16. package/dist/components/modules/auth/Dashboard.d.ts +1 -1
  17. package/dist/components/modules/auth/PostCard.d.ts +25 -24
  18. package/dist/components/modules/auth/PostCard.d.ts.map +1 -1
  19. package/dist/components/modules/auth/PostCard.js +115 -112
  20. package/dist/components/modules/auth/PostCard.js.map +1 -1
  21. package/dist/components/modules/auth/PostInteractionsModal.d.ts +11 -11
  22. package/dist/components/modules/auth/RepostModal.d.ts +21 -21
  23. package/dist/components/modules/auth/SidebarLeft.d.ts +1 -1
  24. package/dist/components/modules/auth/SidebarLeft.d.ts.map +1 -1
  25. package/dist/components/modules/auth/SidebarLeft.js +8 -40
  26. package/dist/components/modules/auth/SidebarLeft.js.map +1 -1
  27. package/dist/components/modules/auth/Stories.d.ts +1 -1
  28. package/dist/components/modules/auth/StoryViewer.d.ts +9 -9
  29. package/dist/components/modules/auth/widgets/EconomyWidget.d.ts +2 -0
  30. package/dist/components/modules/auth/widgets/EconomyWidget.d.ts.map +1 -0
  31. package/dist/components/modules/auth/widgets/EconomyWidget.js +38 -0
  32. package/dist/components/modules/auth/widgets/EconomyWidget.js.map +1 -0
  33. package/dist/components/modules/auth/widgets/LeagueWidget.d.ts +2 -0
  34. package/dist/components/modules/auth/widgets/LeagueWidget.d.ts.map +1 -0
  35. package/dist/components/modules/auth/widgets/LeagueWidget.js +36 -0
  36. package/dist/components/modules/auth/widgets/LeagueWidget.js.map +1 -0
  37. package/dist/components/modules/auth/widgets/MinecraftWidget.d.ts +2 -0
  38. package/dist/components/modules/auth/widgets/MinecraftWidget.d.ts.map +1 -0
  39. package/dist/components/modules/auth/widgets/MinecraftWidget.js +36 -0
  40. package/dist/components/modules/auth/widgets/MinecraftWidget.js.map +1 -0
  41. package/dist/components/modules/auth/widgets/RankingWidget.d.ts +5 -0
  42. package/dist/components/modules/auth/widgets/RankingWidget.d.ts.map +1 -0
  43. package/dist/components/modules/auth/widgets/RankingWidget.js +79 -0
  44. package/dist/components/modules/auth/widgets/RankingWidget.js.map +1 -0
  45. package/dist/components/modules/chat/ChatContainer.d.ts +1 -1
  46. package/dist/components/modules/chat/ChatInput.d.ts +4 -4
  47. package/dist/components/modules/chat/ChatList.d.ts +6 -6
  48. package/dist/components/modules/chat/ChatNotes.d.ts +1 -1
  49. package/dist/components/modules/community/GroupHeader.d.ts +10 -10
  50. package/dist/components/modules/community/GroupMenu.d.ts +9 -9
  51. package/dist/components/modules/community/SchoolCard.d.ts +6 -6
  52. package/dist/components/modules/community/SurveyCard.d.ts +6 -6
  53. package/dist/components/modules/forum/ForumBoard.d.ts +16 -16
  54. package/dist/components/modules/forum/ForumBoard.js +6 -6
  55. package/dist/components/modules/forum/ForumBoard.js.map +1 -1
  56. package/dist/components/modules/forum/TopicItem.d.ts +15 -15
  57. package/dist/components/modules/forum/TopicItem.js +6 -6
  58. package/dist/components/modules/forum/TopicItem.js.map +1 -1
  59. package/dist/components/modules/guest/Introduction.d.ts +1 -1
  60. package/dist/components/modules/magaza/BackToStore.d.ts +1 -1
  61. package/dist/components/modules/magaza/StoreHeader.d.ts +5 -5
  62. package/dist/components/modules/news/NewsCard.d.ts +11 -11
  63. package/dist/components/modules/news/NewsComments.d.ts +1 -1
  64. package/dist/components/modules/profile/ProfileContent.d.ts +4 -4
  65. package/dist/components/modules/profile/ProfileContent.d.ts.map +1 -1
  66. package/dist/components/modules/profile/ProfileContent.js +98 -70
  67. package/dist/components/modules/profile/ProfileContent.js.map +1 -1
  68. package/dist/components/modules/profile/ProfileHeader.d.ts +7 -7
  69. package/dist/components/modules/profile/ProfileHeader.js +19 -19
  70. package/dist/components/modules/profile/ProfileHeader.js.map +1 -1
  71. package/dist/components/modules/profile/ProfileStats.d.ts +6 -1
  72. package/dist/components/modules/profile/ProfileStats.d.ts.map +1 -1
  73. package/dist/components/modules/profile/ProfileStats.js +11 -6
  74. package/dist/components/modules/profile/ProfileStats.js.map +1 -1
  75. package/dist/components/modules/profile/TeamSelectorModal.d.ts +10 -10
  76. package/dist/components/modules/profile/tabs/AboutTab.d.ts +10 -0
  77. package/dist/components/modules/profile/tabs/AboutTab.d.ts.map +1 -0
  78. package/dist/components/modules/profile/tabs/AboutTab.js +9 -0
  79. package/dist/components/modules/profile/tabs/AboutTab.js.map +1 -0
  80. package/dist/components/modules/profile/tabs/CareerTab.d.ts +7 -0
  81. package/dist/components/modules/profile/tabs/CareerTab.d.ts.map +1 -0
  82. package/dist/components/modules/profile/tabs/CareerTab.js +46 -0
  83. package/dist/components/modules/profile/tabs/CareerTab.js.map +1 -0
  84. package/dist/components/modules/profile/tabs/FriendsTab.d.ts +7 -0
  85. package/dist/components/modules/profile/tabs/FriendsTab.d.ts.map +1 -0
  86. package/dist/components/modules/profile/tabs/FriendsTab.js +8 -0
  87. package/dist/components/modules/profile/tabs/FriendsTab.js.map +1 -0
  88. package/dist/components/modules/profile/tabs/GamesTab.d.ts +7 -0
  89. package/dist/components/modules/profile/tabs/GamesTab.d.ts.map +1 -0
  90. package/dist/components/modules/profile/tabs/GamesTab.js +37 -0
  91. package/dist/components/modules/profile/tabs/GamesTab.js.map +1 -0
  92. package/dist/components/modules/profile/tabs/PostsTab.d.ts +7 -0
  93. package/dist/components/modules/profile/tabs/PostsTab.d.ts.map +1 -0
  94. package/dist/components/modules/profile/tabs/PostsTab.js +81 -0
  95. package/dist/components/modules/profile/tabs/PostsTab.js.map +1 -0
  96. package/dist/components/modules/profile/widgets/ProfileBadgesWidget.d.ts +2 -0
  97. package/dist/components/modules/profile/widgets/ProfileBadgesWidget.d.ts.map +1 -0
  98. package/dist/components/modules/profile/widgets/ProfileBadgesWidget.js +6 -0
  99. package/dist/components/modules/profile/widgets/ProfileBadgesWidget.js.map +1 -0
  100. package/dist/components/modules/profile/widgets/ProfileCloudWidget.d.ts +6 -0
  101. package/dist/components/modules/profile/widgets/ProfileCloudWidget.d.ts.map +1 -0
  102. package/dist/components/modules/profile/widgets/ProfileCloudWidget.js +6 -0
  103. package/dist/components/modules/profile/widgets/ProfileCloudWidget.js.map +1 -0
  104. package/dist/components/modules/profile/widgets/ProfileFriendsWidget.d.ts +8 -0
  105. package/dist/components/modules/profile/widgets/ProfileFriendsWidget.d.ts.map +1 -0
  106. package/dist/components/modules/profile/widgets/ProfileFriendsWidget.js +12 -0
  107. package/dist/components/modules/profile/widgets/ProfileFriendsWidget.js.map +1 -0
  108. package/dist/components/modules/stations/StationCard.d.ts +2 -2
  109. package/dist/components/modules/stations/StationQRModal.d.ts +9 -9
  110. package/dist/components/shared/DevTools.d.ts +2 -0
  111. package/dist/components/shared/DevTools.d.ts.map +1 -0
  112. package/dist/components/shared/DevTools.js +39 -0
  113. package/dist/components/shared/DevTools.js.map +1 -0
  114. package/dist/components/shared/FloatingChatButton.d.ts +4 -4
  115. package/dist/components/shared/Header.d.ts +1 -1
  116. package/dist/components/shared/Header.d.ts.map +1 -1
  117. package/dist/components/shared/Header.js +108 -97
  118. package/dist/components/shared/Header.js.map +1 -1
  119. package/dist/components/shared/LoginModal.d.ts +4 -4
  120. package/dist/components/shared/LoginModal.d.ts.map +1 -1
  121. package/dist/components/shared/LoginModal.js +65 -69
  122. package/dist/components/shared/LoginModal.js.map +1 -1
  123. package/dist/components/shared/MainLayoutWrapper.d.ts +3 -3
  124. package/dist/components/showcase/ProfileTab.d.ts.map +1 -1
  125. package/dist/components/showcase/ProfileTab.js +43 -3
  126. package/dist/components/showcase/ProfileTab.js.map +1 -1
  127. package/dist/components/showcase/SocialTab.d.ts.map +1 -1
  128. package/dist/components/showcase/SocialTab.js +86 -2
  129. package/dist/components/showcase/SocialTab.js.map +1 -1
  130. package/dist/context/ArmoyuContext.d.ts +42 -0
  131. package/dist/context/ArmoyuContext.d.ts.map +1 -0
  132. package/dist/context/ArmoyuContext.js +76 -0
  133. package/dist/context/ArmoyuContext.js.map +1 -0
  134. package/dist/context/AuthContext.d.ts +18 -18
  135. package/dist/context/AuthContext.d.ts.map +1 -1
  136. package/dist/context/AuthContext.js +97 -74
  137. package/dist/context/AuthContext.js.map +1 -1
  138. package/dist/context/CartContext.d.ts +16 -16
  139. package/dist/context/SocketContext.d.ts +12 -12
  140. package/dist/context/SocketContext.d.ts.map +1 -1
  141. package/dist/context/SocketContext.js +31 -30
  142. package/dist/context/SocketContext.js.map +1 -1
  143. package/dist/index.d.ts +67 -65
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +83 -80
  146. package/dist/index.js.map +1 -1
  147. package/dist/lib/ArmoyuUI.d.ts +18 -0
  148. package/dist/lib/ArmoyuUI.d.ts.map +1 -0
  149. package/dist/lib/ArmoyuUI.js +25 -0
  150. package/dist/lib/ArmoyuUI.js.map +1 -0
  151. package/dist/lib/constants/educationData.d.ts +7 -7
  152. package/dist/lib/constants/seedData.d.ts +164 -164
  153. package/dist/lib/constants/seedData.d.ts.map +1 -1
  154. package/dist/lib/constants/seedData.js +694 -694
  155. package/dist/lib/constants/seedData.js.map +1 -1
  156. package/dist/lib/constants/stationData.d.ts +13 -13
  157. package/dist/lib/constants/stationData.js +166 -166
  158. package/dist/lib/constants/stationData.js.map +1 -1
  159. package/dist/lib/constants/surveyData.d.ts +2 -2
  160. package/dist/lib/constants/teamData.d.ts +12 -12
  161. package/package.json +14 -12
  162. package/next.config.ts +0 -13
  163. package/postcss.config.js +0 -6
  164. package/src/app/layout.tsx +0 -67
  165. package/src/app/page.tsx +0 -101
  166. package/src/components/Button.tsx +0 -41
  167. package/src/components/GenderStatsBar.tsx +0 -66
  168. package/src/components/RollingNumber.tsx +0 -50
  169. package/src/components/Slider.tsx +0 -114
  170. package/src/components/StatsGrid.tsx +0 -35
  171. package/src/components/ViewModeToggle.tsx +0 -39
  172. package/src/components/modules/auth/Dashboard.tsx +0 -649
  173. package/src/components/modules/auth/MediaLightbox.tsx +0 -112
  174. package/src/components/modules/auth/PostCard.tsx +0 -556
  175. package/src/components/modules/auth/PostInteractionsModal.tsx +0 -138
  176. package/src/components/modules/auth/RepostModal.tsx +0 -167
  177. package/src/components/modules/auth/SidebarLeft.tsx +0 -237
  178. package/src/components/modules/auth/Stories.tsx +0 -69
  179. package/src/components/modules/auth/StoryViewer.tsx +0 -146
  180. package/src/components/modules/chat/ChatContainer.tsx +0 -332
  181. package/src/components/modules/chat/ChatInput.tsx +0 -57
  182. package/src/components/modules/chat/ChatList.tsx +0 -179
  183. package/src/components/modules/chat/ChatMessage.tsx +0 -43
  184. package/src/components/modules/chat/ChatNotes.tsx +0 -58
  185. package/src/components/modules/community/GroupHeader.tsx +0 -111
  186. package/src/components/modules/community/GroupMenu.tsx +0 -82
  187. package/src/components/modules/community/SchoolCard.tsx +0 -104
  188. package/src/components/modules/community/SurveyCard.tsx +0 -149
  189. package/src/components/modules/forum/ForumBoard.tsx +0 -78
  190. package/src/components/modules/forum/ForumPost.tsx +0 -71
  191. package/src/components/modules/forum/NewTopicModal.tsx +0 -112
  192. package/src/components/modules/forum/TopicItem.tsx +0 -72
  193. package/src/components/modules/galleries/GalleryCard.tsx +0 -66
  194. package/src/components/modules/giveaways/GiveawayCard.tsx +0 -76
  195. package/src/components/modules/groups/ApplicationModal.tsx +0 -133
  196. package/src/components/modules/groups/GroupCard.tsx +0 -96
  197. package/src/components/modules/guest/Introduction.tsx +0 -60
  198. package/src/components/modules/magaza/BackToStore.tsx +0 -53
  199. package/src/components/modules/magaza/StoreHeader.tsx +0 -74
  200. package/src/components/modules/news/NewsCard.tsx +0 -66
  201. package/src/components/modules/news/NewsComments.tsx +0 -141
  202. package/src/components/modules/profile/CloudStorageModal.tsx +0 -200
  203. package/src/components/modules/profile/EditProfileModal.tsx +0 -191
  204. package/src/components/modules/profile/ProfileContent.tsx +0 -491
  205. package/src/components/modules/profile/ProfileHeader.tsx +0 -128
  206. package/src/components/modules/profile/ProfileStats.tsx +0 -72
  207. package/src/components/modules/profile/TeamSelectorModal.tsx +0 -129
  208. package/src/components/modules/stations/StationCard.tsx +0 -95
  209. package/src/components/modules/stations/StationQRModal.tsx +0 -102
  210. package/src/components/shared/FloatingChatButton.tsx +0 -57
  211. package/src/components/shared/Footer.tsx +0 -77
  212. package/src/components/shared/Header.tsx +0 -799
  213. package/src/components/shared/LoginModal.tsx +0 -208
  214. package/src/components/shared/MainLayoutWrapper.tsx +0 -15
  215. package/src/components/shared/PageWidth.tsx +0 -22
  216. package/src/components/showcase/CommunityTab.tsx +0 -22
  217. package/src/components/showcase/CorporateTab.tsx +0 -38
  218. package/src/components/showcase/GeneralTab.tsx +0 -41
  219. package/src/components/showcase/MessagesTab.tsx +0 -26
  220. package/src/components/showcase/ProfileTab.tsx +0 -20
  221. package/src/components/showcase/ShopTab.tsx +0 -24
  222. package/src/components/showcase/SocialTab.tsx +0 -28
  223. package/src/context/AuthContext.tsx +0 -104
  224. package/src/context/CartContext.tsx +0 -93
  225. package/src/context/ChatContext.tsx +0 -32
  226. package/src/context/LayoutContext.tsx +0 -29
  227. package/src/context/SocketContext.tsx +0 -50
  228. package/src/context/ThemeContext.tsx +0 -52
  229. package/src/index.ts +0 -96
  230. package/src/lib/constants/educationData.ts +0 -124
  231. package/src/lib/constants/punishmentData.ts +0 -201
  232. package/src/lib/constants/seedData.ts +0 -758
  233. package/src/lib/constants/stationData.ts +0 -170
  234. package/src/lib/constants/surveyData.ts +0 -53
  235. package/src/lib/constants/teamData.ts +0 -69
  236. package/src/lib/utils/numberFormat.ts +0 -16
  237. package/src/lib/utils/odpUtils.ts +0 -51
  238. package/src/types/index.ts +0 -1
  239. package/src/types/stats.ts +0 -17
@@ -1,649 +0,0 @@
1
- import React, { useState, useEffect, useRef, useMemo } from 'react';
2
- import { useSearchParams, useRouter } from 'next/navigation';
3
- import { useAuth } from '../../../context/AuthContext';
4
- import { useSocket } from '../../../context/SocketContext';
5
- import { PostCard } from './PostCard';
6
- import { Stories } from './Stories';
7
- import { SidebarLeft } from './SidebarLeft';
8
- import { CloudStorageModal } from '../profile/CloudStorageModal';
9
- import Link from 'next/link';
10
- import { userList, postList, groupList } from '../../../lib/constants/seedData';
11
- import { Post, Group } from '@armoyu/core';
12
- import { CheckCircle2, ArrowLeft } from 'lucide-react';
13
-
14
- export function Dashboard() {
15
- const { user } = useAuth();
16
- const { on } = useSocket();
17
- const searchParams = useSearchParams();
18
- const router = useRouter();
19
-
20
- const focusedPostId = searchParams.get('post');
21
-
22
- const [isCloudModalOpen, setIsCloudModalOpen] = useState(false);
23
- const [isBioModalOpen, setIsBioModalOpen] = useState(false);
24
- const [tempBio, setTempBio] = useState(user?.bio || '');
25
- const [selectedMedia, setSelectedMedia] = useState<{ url: string, type: 'image' | 'video' }[]>([]);
26
- const [selectedTag, setSelectedTag] = useState<string | null>(null);
27
- const [visibleCount, setVisibleCount] = useState(10);
28
- const [isLoadingMore, setIsLoadingMore] = useState(false);
29
-
30
- const { updateUser } = useAuth();
31
- const [posts, setPosts] = useState<Post[]>(postList);
32
- const [newPostsBuffer, setNewPostsBuffer] = useState<Post[]>([]);
33
- const [isAtTop, setIsAtTop] = useState(true);
34
- const [postContent, setPostContent] = useState('');
35
- const [isPosting, setIsPosting] = useState(false);
36
- const textareaRef = useRef<HTMLTextAreaElement>(null);
37
-
38
- const handleBioSave = () => {
39
- if (user) {
40
- updateUser({
41
- ...user,
42
- bio: tempBio
43
- } as any);
44
- setIsBioModalOpen(false);
45
- }
46
- };
47
-
48
- // Gündemdeki Etiketleri Dinamik Hesapla
49
- const trendingTags = useMemo(() => {
50
- const counts: Record<string, number> = {};
51
- posts.forEach(post => {
52
- post.hashtags?.forEach(tag => {
53
- counts[tag] = (counts[tag] || 0) + 1;
54
- });
55
- });
56
- return Object.entries(counts)
57
- .map(([name, count]) => ({ name, count }))
58
- .sort((a, b) => b.count - a.count)
59
- .slice(0, 5);
60
- }, [posts]);
61
-
62
- // Filtremele ve Pagination Mantığı
63
- const allFilteredPosts = useMemo(() => {
64
- // 1. Post ID filtresi (En yüksek öncelik)
65
- if (focusedPostId) {
66
- return posts.filter(p => p.id === focusedPostId);
67
- }
68
-
69
- // 2. Tag filtresi
70
- if (selectedTag) {
71
- return posts.filter(post => post.hashtags?.includes(selectedTag.replace('#', '')));
72
- }
73
-
74
- return posts;
75
- }, [posts, focusedPostId, selectedTag]);
76
-
77
- const visiblePosts = allFilteredPosts.slice(0, visibleCount);
78
-
79
- // Auto-resize logic for textarea
80
- useEffect(() => {
81
- if (textareaRef.current) {
82
- textareaRef.current.style.height = 'inherit';
83
- textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
84
- }
85
- }, [postContent]);
86
-
87
- useEffect(() => {
88
- const handleScroll = () => {
89
- setIsAtTop(window.scrollY < 150);
90
- };
91
- window.addEventListener('scroll', handleScroll);
92
- return () => window.removeEventListener('scroll', handleScroll);
93
- }, []);
94
-
95
- // Socket Listener for New Posts
96
- useEffect(() => {
97
- console.log('[Dashboard] Setting up socket listener for "post" event');
98
- const offPost = on('post', (data: any) => {
99
- console.log('[Dashboard] New socket post received!', data);
100
- const newPost = Post.fromJSON(data);
101
-
102
- setPosts(currentPosts => {
103
- // If this is a post from the CURRENT USER, find the pending version and replace it
104
- if (newPost.author?.username === user?.username) {
105
- // Check if there is a pending post (we look for matches in content and media count as a heuristic)
106
- const pendingIdx = currentPosts.findIndex(p => p.isPending && p.content === newPost.content);
107
- if (pendingIdx !== -1) {
108
- const updated = [...currentPosts];
109
- updated[pendingIdx] = newPost; // Replace pending with confirmed
110
- return updated;
111
- }
112
- }
113
-
114
- // Standard duplicate check
115
- if (currentPosts.some(p => p.id === newPost.id)) return currentPosts;
116
-
117
- if (window.scrollY < 150) {
118
- return [newPost, ...currentPosts];
119
- } else {
120
- setNewPostsBuffer(prev => {
121
- if (prev.some(p => p.id === newPost.id)) return prev;
122
- return [newPost, ...prev];
123
- });
124
- return currentPosts;
125
- }
126
- });
127
- });
128
-
129
- const offLike = on('post_like', (data: any) => {
130
- const { postId, newCount } = data;
131
- setPosts(currentPosts =>
132
- currentPosts.map(p => {
133
- if (p.id === postId) {
134
- return {
135
- ...p,
136
- stats: { ...p.stats, likes: newCount }
137
- };
138
- }
139
- return p;
140
- })
141
- );
142
- });
143
-
144
- const offRepostCount = on('post_repost_count', (data: any) => {
145
- const { postId } = data;
146
- setPosts(currentPosts =>
147
- currentPosts.map(p => {
148
- if (p.id === postId) {
149
- return {
150
- ...p,
151
- stats: { ...p.stats, reposts: (p.stats.reposts || 0) + 1 }
152
- };
153
- }
154
- return p;
155
- })
156
- );
157
- });
158
-
159
- return () => {
160
- offPost();
161
- offLike();
162
- offRepostCount();
163
- };
164
- }, [on]);
165
-
166
- const mergeNewPosts = () => {
167
- setPosts(prev => [...newPostsBuffer, ...prev]);
168
- setNewPostsBuffer([]);
169
- window.scrollTo({ top: 0, behavior: 'smooth' });
170
- };
171
-
172
- const { emit } = useSocket();
173
-
174
- const handleCreatePost = () => {
175
- try {
176
- if ((!postContent.trim() && selectedMedia.length === 0) || isPosting || !user) {
177
- return;
178
- }
179
-
180
- // 1. Create optimistic local post
181
- const tempId = 'p-temp-' + Date.now();
182
- const optimisticPost = new Post({
183
- id: tempId,
184
- author: user,
185
- content: postContent,
186
- media: selectedMedia,
187
- createdAt: 'Gönderiliyor...',
188
- stats: { likes: 0, comments: 0, shares: 0, reposts: 0 },
189
- hashtags: postContent.match(/#\w+/g)?.map(t => t.replace('#', '')) || [],
190
- isPending: true
191
- });
192
-
193
- // 2. Clear inputs & Add to state immediately
194
- const savedContent = postContent;
195
- const savedMedia = [...selectedMedia];
196
-
197
- setPosts(prev => [optimisticPost, ...prev]);
198
- setPostContent('');
199
- setSelectedMedia([]);
200
-
201
- console.log('[Dashboard] Optimistic post added, inputs cleared.');
202
-
203
- // 3. Prepare wire data
204
- const wireData = {
205
- id: 'p-' + Date.now(), // Real ID candidate
206
- author: {
207
- id: user.id,
208
- username: user.username,
209
- displayName: user.displayName,
210
- avatar: user.avatar,
211
- role: user.role,
212
- verified: user.verified,
213
- level: user.level
214
- },
215
- content: savedContent,
216
- media: savedMedia,
217
- createdAt: 'Şimdi',
218
- stats: { likes: 0, comments: 0, shares: 0, reposts: 0 },
219
- hashtags: savedContent.match(/#\w+/g)?.map(t => t.replace('#', '')) || []
220
- };
221
-
222
- // 4. Emit to socket server
223
- emit('post', wireData);
224
-
225
- } catch (error) {
226
- console.error('[Dashboard] Error in handleCreatePost:', error);
227
- }
228
- };
229
-
230
- // Sonsuz Kaydırma Trigger (Intersection Observer)
231
- const loaderRef = useRef<HTMLDivElement>(null);
232
-
233
- useEffect(() => {
234
- const observer = new IntersectionObserver(
235
- (entries) => {
236
- if (entries[0].isIntersecting && !isLoadingMore && visibleCount < allFilteredPosts.length) {
237
- setIsLoadingMore(true);
238
- setTimeout(() => {
239
- setVisibleCount(prev => prev + 10);
240
- setIsLoadingMore(false);
241
- }, 800);
242
- }
243
- },
244
- { threshold: 0.1 }
245
- );
246
-
247
- if (loaderRef.current) {
248
- observer.observe(loaderRef.current);
249
- }
250
-
251
- return () => observer.disconnect();
252
- }, [isLoadingMore, visibleCount, allFilteredPosts.length]);
253
-
254
- return (
255
- <div className="w-full flex-1 flex gap-6 pb-20 animate-in fade-in slide-in-from-bottom-8 duration-700 items-start">
256
-
257
- {/* Sol Yan Panel (Ranking & Economy & MC) */}
258
- <SidebarLeft />
259
-
260
-
261
- {/* Ana Akış (Feed) */}
262
- <div className="flex-1 flex flex-col pt-2">
263
-
264
- {/* Hikayeler (Stories) */}
265
- <Stories />
266
-
267
- {/* Yeni Gönderi Paylaşma Alanı */}
268
- <div className="glass-panel p-4 md:p-5 rounded-3xl border border-armoyu-card-border bg-armoyu-card-bg shadow-sm mb-8">
269
- <div className="flex gap-4 items-start">
270
- <img
271
- src={user?.avatar || "https://api.dicebear.com/7.x/avataaars/svg?seed=Armoyu"}
272
- alt="Avatar"
273
- className="w-12 h-12 rounded-full border border-black/10 dark:border-white/10 shadow-sm mt-1"
274
- />
275
- <div className="flex-1 flex flex-col gap-3">
276
- <textarea
277
- ref={textareaRef}
278
- value={postContent}
279
- onChange={(e) => setPostContent(e.target.value)}
280
- onKeyDown={(e) => {
281
- if (e.key === 'Enter' && !e.shiftKey) {
282
- e.preventDefault();
283
- handleCreatePost();
284
- }
285
- }}
286
- placeholder="Neler yapıyorsun, düşüncelerini paylaş..."
287
- className="w-full bg-black/5 dark:bg-white/5 border border-black/10 dark:border-white/10 hover:border-black/20 dark:hover:border-white/20 rounded-2xl px-5 py-3 text-sm text-armoyu-text placeholder-armoyu-text-muted focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all font-medium resize-none min-h-[44px] max-h-[300px] overflow-y-auto"
288
- ></textarea>
289
-
290
- {/* Seçili Medya Önizlemesi */}
291
- {selectedMedia.length > 0 && (
292
- <div className="flex gap-2.5 overflow-x-auto pb-2 scrollbar-hide animate-in fade-in slide-in-from-left-4 duration-300">
293
- {selectedMedia.map((media, idx) => (
294
- <div key={idx} className="relative group shrink-0">
295
- {media.type === 'video' ? (
296
- <div className="w-24 h-24 rounded-2xl bg-black/20 flex items-center justify-center border border-white/10 overflow-hidden">
297
- <video src={media.url} className="w-full h-full object-cover opacity-60" />
298
- <div className="absolute inset-0 flex items-center justify-center">
299
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="white"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
300
- </div>
301
- </div>
302
- ) : (
303
- <img
304
- src={media.url}
305
- alt="Preview"
306
- className="w-24 h-24 rounded-2xl object-cover border border-white/10 shadow-md group-hover:scale-105 transition-transform"
307
- />
308
- )}
309
- <button
310
- onClick={() => setSelectedMedia(prev => prev.filter((_, i) => i !== idx))}
311
- className="absolute -top-1.5 -right-1.5 w-6 h-6 bg-red-500 text-white rounded-full flex items-center justify-center shadow-lg hover:bg-red-600 transition-colors z-10"
312
- >
313
- <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
314
- </button>
315
- </div>
316
- ))}
317
- </div>
318
- )}
319
- </div>
320
- </div>
321
- <div className="flex justify-between items-center mt-3 pl-16">
322
- <div className="flex gap-2">
323
- <button
324
- onClick={() => setIsCloudModalOpen(true)}
325
- className="flex items-center justify-center p-2.5 text-blue-500 hover:bg-blue-500/10 rounded-xl transition-colors shrink-0"
326
- title="Cloud Medya Galerisini Aç"
327
- >
328
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round" className="text-blue-500"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path></svg>
329
- </button>
330
- <button className="p-2 text-armoyu-text-muted hover:text-blue-500 hover:bg-blue-500/10 rounded-full transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg></button>
331
- <button className="p-2 text-armoyu-text-muted hover:text-emerald-500 hover:bg-emerald-500/10 rounded-full transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line></svg></button>
332
- </div>
333
- <button
334
- onClick={handleCreatePost}
335
- disabled={isPosting || (!postContent.trim() && selectedMedia.length === 0)}
336
- className="px-6 py-2 bg-gradient-to-r from-blue-600 to-blue-500 hover:from-blue-500 hover:to-blue-400 disabled:opacity-50 disabled:cursor-not-allowed text-white text-sm font-bold rounded-xl shadow-md transition-all active:scale-95"
337
- >
338
- {isPosting ? 'Gidiyor...' : 'Gönder'}
339
- </button>
340
- </div>
341
- </div>
342
-
343
- {/* Tekil Gönderi Filtre Banner'ı */}
344
- {focusedPostId && (
345
- <div className="flex items-center justify-between bg-blue-600/10 border border-blue-600/20 p-5 rounded-3xl mb-6 animate-in fade-in zoom-in duration-500">
346
- <div className="flex items-center gap-4">
347
- <div className="w-10 h-10 rounded-full bg-blue-600/20 flex items-center justify-center text-blue-600">
348
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></svg>
349
- </div>
350
- <div>
351
- <h4 className="text-sm font-black text-armoyu-text uppercase tracking-tight">Tekil Gönderi Modu</h4>
352
- <p className="text-xs text-armoyu-text-muted font-bold">Şu an sadece bu bildirime ait paylaşımı görüyorsunuz.</p>
353
- </div>
354
- </div>
355
- <button
356
- onClick={() => router.push('/')}
357
- className="px-5 py-2 bg-blue-600 text-white text-xs font-black rounded-xl hover:bg-blue-500 shadow-md transition-all active:scale-95 uppercase tracking-widest"
358
- >
359
- Tüm Akışa Dön
360
- </button>
361
- </div>
362
- )}
363
-
364
- {/* Yeni Paylaşım Banner'ı - Bottom Center Fixed */}
365
- {newPostsBuffer.length > 0 && (
366
- <div className="fixed bottom-12 left-1/2 -translate-x-1/2 z-[60] flex justify-center pointer-events-none">
367
- <button
368
- onClick={mergeNewPosts}
369
- className="pointer-events-auto flex items-center gap-3 px-8 py-3 bg-blue-600/95 backdrop-blur-xl text-white text-sm font-black rounded-full shadow-[0_15px_35px_rgba(37,99,235,0.45)] border border-white/30 hover:bg-blue-500 hover:scale-105 hover:-translate-y-1 transition-all animate-in slide-in-from-bottom-12 fade-in duration-500"
370
- >
371
- <div className="flex -space-x-2">
372
- {newPostsBuffer.slice(0, 3).map((p, i) => (
373
- <img
374
- key={i}
375
- src={p.author?.avatar}
376
- className="w-7 h-7 rounded-full border-2 border-white shadow-sm bg-armoyu-card-bg"
377
- />
378
- ))}
379
- </div>
380
- <span className="whitespace-nowrap">{newPostsBuffer.length} Yeni Paylaşımı Görüntüle</span>
381
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="m18 15-6-6-6 6" /></svg>
382
- </button>
383
- </div>
384
- )}
385
-
386
- {/* Post Akışı Tablosu */}
387
- <div className="space-y-6">
388
- {selectedTag && (
389
- <div className="flex items-center justify-between bg-blue-500/10 border border-blue-500/20 p-4 rounded-2xl animate-in fade-in slide-in-from-left-4 duration-300">
390
- <div className="flex items-center gap-2">
391
- <span className="text-sm font-bold text-armoyu-text-muted">Filtrelenen Etiket:</span>
392
- <span className="text-sm font-black text-blue-500">{selectedTag}</span>
393
- </div>
394
- <button
395
- onClick={() => { setSelectedTag(null); setVisibleCount(10); }}
396
- className="text-xs font-bold text-red-500 hover:underline"
397
- >
398
- Filtreyi Temizle
399
- </button>
400
- </div>
401
- )}
402
- {visiblePosts.length > 0 ? (
403
- visiblePosts.map(post => (
404
- <PostCard
405
- key={post.id}
406
- {...post}
407
- onTagClick={(tag: string) => { setSelectedTag(tag); setVisibleCount(10); }}
408
- />
409
- ))
410
- ) : (
411
- <div className="text-center py-20 bg-black/5 dark:bg-white/5 rounded-3xl border border-dashed border-armoyu-card-border">
412
- <p className="text-armoyu-text-muted font-bold">Bu etikete ait henüz bir paylaşım yok.</p>
413
- </div>
414
- )}
415
-
416
- {/* Infinity Scroll Loader Area */}
417
- <div ref={loaderRef} className="py-10 flex flex-col items-center justify-center gap-3">
418
- {visibleCount < allFilteredPosts.length ? (
419
- <>
420
- <div className="w-8 h-8 border-4 border-blue-500/20 border-t-blue-500 rounded-full animate-spin"></div>
421
- <p className="text-xs font-bold text-armoyu-text-muted animate-pulse italic">Daha fazla içerik yükleniyor...</p>
422
- </>
423
- ) : (
424
- <div className="flex items-center gap-4 opacity-50">
425
- <div className="h-px w-20 bg-armoyu-card-border"></div>
426
- <span className="text-[10px] uppercase font-black tracking-widest text-armoyu-text-muted">Tüm akış görüntülendi</span>
427
- <div className="h-px w-20 bg-armoyu-card-border"></div>
428
- </div>
429
- )}
430
- </div>
431
- </div>
432
- </div>
433
-
434
- {/* Sağ Yan Panel (Sidebar Widget Area) */}
435
- <div className="hidden lg:flex w-[320px] flex-col gap-6">
436
- {/* Kullanıcı Profili Widget - Gelişmiş */}
437
- <div className="glass-panel p-6 rounded-3xl border border-armoyu-card-border bg-armoyu-card-bg group overflow-hidden relative">
438
- {/* Arkaplan Süsü */}
439
- <div className="absolute -top-10 -right-10 w-32 h-32 bg-blue-500/5 rounded-full blur-3xl group-hover:bg-blue-500/10 transition-all duration-700" />
440
-
441
- <div className="relative z-10">
442
- <h3 className="font-extrabold text-armoyu-text text-xl tracking-tight mb-6">
443
- Hoş Geldin, <span className="text-blue-500">{user?.displayName?.split(' ')[0]}</span>
444
- </h3>
445
-
446
- {/* Görev Sistemi */}
447
- {(() => {
448
- const steps = [
449
- { id: 'avatar', label: 'Profil Fotoğrafı Ekle', completed: !!user?.avatar && !user.avatar.includes('seed=Armoyu'), icon: '🖼️' },
450
- { id: 'bio', label: 'Hakkında Yazısı Yaz', completed: !!user?.bio && user.bio.length > 5, icon: '✍️' },
451
- { id: 'verified', label: 'E-posta Onayla', completed: !!user?.verified, icon: '📧' },
452
- { id: 'groups', label: 'Bir Gruba Katıl', completed: (user?.groups?.length || 0) > 0, icon: '🛡️' }
453
- ];
454
- const totalPercentage = steps.reduce((acc, step) => acc + (step.completed ? 25 : 0), 0);
455
- const nextStep = steps.find(s => !s.completed);
456
-
457
- if (totalPercentage === 100) {
458
- return (
459
- <div className="flex items-center gap-2 animate-in fade-in duration-700">
460
- <CheckCircle2 size={16} className="text-emerald-500" />
461
- <span className="text-[10px] font-black text-emerald-500 uppercase tracking-widest">Tüm görevler tamamlandı</span>
462
- </div>
463
- );
464
- }
465
-
466
- return (
467
- <div className="animate-in fade-in slide-in-from-top-4 duration-500">
468
- <div className="flex items-center justify-between mb-4">
469
- <span className="text-[10px] font-black text-armoyu-text-muted uppercase tracking-widest">Aktif Görevin</span>
470
- <span className="text-[10px] font-black text-blue-500 uppercase tracking-widest bg-blue-500/10 px-2 py-0.5 rounded">%{totalPercentage} Tamamlandı</span>
471
- </div>
472
-
473
- <button
474
- onClick={() => {
475
- if (nextStep?.id === 'bio') {
476
- setIsBioModalOpen(true);
477
- } else if (nextStep?.id === 'groups') {
478
- router.push('/gruplar');
479
- } else {
480
- router.push('/ayarlar/profil');
481
- }
482
- }}
483
- className="w-full flex items-center gap-4 p-4 bg-black/20 hover:bg-blue-600 border border-white/5 rounded-2xl group/task transition-all active:scale-95 shadow-xl text-left"
484
- >
485
- <div className="w-12 h-12 rounded-xl bg-white/5 flex items-center justify-center text-2xl group-hover/task:bg-white/20 transition-colors">
486
- {nextStep?.icon}
487
- </div>
488
- <div className="flex-1">
489
- <h4 className="text-sm font-black text-armoyu-text group-hover/task:text-white uppercase tracking-tight">{nextStep?.label}</h4>
490
- <p className="text-[10px] font-bold text-armoyu-text-muted group-hover/task:text-white/80 uppercase tracking-widest mt-1 italic">Hemen Tamamla →</p>
491
- </div>
492
- </button>
493
- </div>
494
- );
495
- })()}
496
- </div>
497
- </div>
498
-
499
- {/* Gruplarım Widget (Dynamic) - Sadece grupları varsa göster */}
500
- {(user?.groups?.length || 0) > 0 && (
501
- <div className="glass-panel p-6 rounded-3xl border border-armoyu-card-border bg-armoyu-card-bg transition-all animate-in fade-in zoom-in duration-500">
502
- <div className="flex items-center justify-between mb-5">
503
- <h3 className="font-extrabold text-armoyu-text text-lg">Gruplarım</h3>
504
- <span className="bg-blue-500/10 text-blue-500 text-[10px] font-black px-2 py-0.5 rounded-md uppercase">{(user?.groups?.length || 0)} Grup</span>
505
- </div>
506
-
507
- <div className="space-y-4">
508
- {user?.groups?.map((group: any, idx: number) => (
509
- <Link
510
- key={idx}
511
- href={`/gruplar/${group.name.toLowerCase().replace(/\s+/g, '-')}`}
512
- className="flex items-center gap-3 group cursor-pointer p-1 rounded-xl hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
513
- >
514
- <img src={group.logo} alt={group.name} className="w-10 h-10 rounded-xl object-cover border border-black/5 shadow-sm group-hover:scale-105 transition-transform" />
515
- <div className="flex-1 min-w-0">
516
- <h4 className="text-sm font-bold text-armoyu-text truncate group-hover:text-blue-500 transition-colors uppercase tracking-tight">{group.name}</h4>
517
- <div className="flex items-center gap-1.5 mt-0.5">
518
- <span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse" />
519
- <span className="text-[10px] text-armoyu-text-muted truncate opacity-80 uppercase font-bold tracking-widest">{group.shortName} • AKTİF</span>
520
- </div>
521
- </div>
522
- </Link>
523
- ))}
524
- </div>
525
- </div>
526
- )}
527
-
528
- {/* Gündemdekiler Widget */}
529
- <div className="glass-panel p-6 rounded-3xl border border-armoyu-card-border bg-armoyu-card-bg">
530
- <h3 className="font-extrabold text-armoyu-text mb-5 text-lg">Gündemdeki Etiketler</h3>
531
- <div className="space-y-4">
532
- {trendingTags.map((tagObj: { name: string, count: number }, idx: number) => (
533
- <div
534
- key={idx}
535
- className={`flex justify-between items-center cursor-pointer group p-2 rounded-xl transition-all ${selectedTag === tagObj.name ? 'bg-blue-500/10' : 'hover:bg-black/5 dark:hover:bg-white/5'}`}
536
- onClick={() => { setSelectedTag(tagObj.name === selectedTag ? null : tagObj.name); setVisibleCount(10); }}
537
- >
538
- <div>
539
- <span className={`block text-sm font-bold transition-colors ${selectedTag === tagObj.name ? 'text-blue-500' : 'text-armoyu-text-muted group-hover:text-blue-500'}`}>{tagObj.name}</span>
540
- <span className="block text-[11px] text-armoyu-text-muted opacity-70 mt-0.5">{tagObj.count} Gönderi</span>
541
- </div>
542
- <button className={`text-xs border rounded-full w-7 h-7 flex items-center justify-center transition-colors ${selectedTag === tagObj.name ? 'bg-blue-500 border-blue-500 text-white' : 'bg-black/5 dark:bg-white/5 border-black/5 dark:border-transparent text-armoyu-text-muted group-hover:text-armoyu-text'}`}>
543
- {selectedTag === tagObj.name ? (
544
- <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
545
- ) : (
546
- <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle></svg>
547
- )}
548
- </button>
549
- </div>
550
- ))}
551
-
552
- <button className="w-full mt-2 pt-4 border-t border-armoyu-card-border text-blue-500 hover:text-blue-600 dark:hover:text-blue-400 text-sm font-bold flex justify-center transition-colors">
553
- Tümünü Gör
554
- </button>
555
- </div>
556
- </div>
557
-
558
-
559
- {/* Popüler Gruplar Widget */}
560
- <div className="glass-panel p-6 rounded-3xl border border-armoyu-card-border bg-armoyu-card-bg">
561
- <div className="flex items-center justify-between mb-5">
562
- <h3 className="font-extrabold text-armoyu-text text-lg">Popüler Gruplar</h3>
563
- <Link href="/gruplar" className="text-xs font-bold text-blue-500 hover:underline">Tümü</Link>
564
- </div>
565
-
566
- <div className="space-y-4">
567
- {groupList.slice(0, 4).map((group, idx) => (
568
- <Link
569
- key={idx}
570
- href={`/gruplar/${group.name.toLowerCase().replace(/\s+/g, '-')}`}
571
- className="flex items-center gap-3 group cursor-pointer p-1 rounded-xl hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
572
- >
573
- <div className="relative">
574
- <img src={group.logo} alt={group.name} className="w-10 h-10 rounded-xl object-cover border border-black/5 shadow-sm" />
575
- {group.recruitment === 'Açık' && (
576
- <div className="absolute -bottom-1 -right-1 w-3 h-3 bg-emerald-500 rounded-full border-2 border-armoyu-card-bg shadow-sm" title="Alımlar Açık" />
577
- )}
578
- </div>
579
- <div className="flex-1 min-w-0">
580
- <h4 className="text-sm font-bold text-armoyu-text truncate group-hover:text-blue-500 transition-colors uppercase tracking-tight">{group.name}</h4>
581
- <p className="text-[10px] text-armoyu-text-muted truncate opacity-80">{group.category} • {group.recruitment === 'Açık' ? 'Katıl' : 'Kapalı'}</p>
582
- </div>
583
- </Link>
584
- ))}
585
-
586
- <button className="w-full py-3 bg-black/5 dark:bg-white/5 border border-black/5 dark:border-white/5 hover:border-blue-500/30 hover:bg-blue-500/5 text-armoyu-text text-xs font-bold rounded-xl transition-all active:scale-[0.98]">
587
- Yeni Grup Oluştur
588
- </button>
589
- </div>
590
- </div>
591
-
592
- </div>
593
-
594
- {/* Cloud Manager Global Linker */}
595
- <CloudStorageModal
596
- isOpen={isCloudModalOpen}
597
- onClose={() => setIsCloudModalOpen(false)}
598
- onSelectMedia={(url, type) => {
599
- setSelectedMedia(prev => [...prev, { url, type }]);
600
- setIsCloudModalOpen(false);
601
- }}
602
- />
603
-
604
- {/* Bio Güncelleme Modalı */}
605
- {isBioModalOpen && (
606
- <div className="fixed inset-0 z-[200] flex items-center justify-center p-6">
607
- <div className="absolute inset-0 bg-black/60 backdrop-blur-md" onClick={() => setIsBioModalOpen(false)} />
608
- <div className="bg-armoyu-card-bg border border-armoyu-card-border rounded-[40px] w-full max-w-lg relative z-10 shadow-2xl animate-in zoom-in-95 duration-300 overflow-hidden">
609
- <div className="p-8 border-b border-armoyu-card-border flex items-center justify-between bg-black/5">
610
- <div className="flex items-center gap-4">
611
- <div className="w-12 h-12 rounded-2xl bg-blue-500/10 flex items-center justify-center text-blue-500 text-2xl">
612
- ✍️
613
- </div>
614
- <div>
615
- <h3 className="text-xl font-black text-armoyu-text uppercase tracking-tight italic">Hakkında Yazısı Yaz</h3>
616
- <p className="text-xs font-medium text-armoyu-text-muted">Profilinde kendini ifade et.</p>
617
- </div>
618
- </div>
619
- <button onClick={() => setIsBioModalOpen(false)} className="p-2 text-armoyu-text-muted hover:text-armoyu-text bg-black/10 rounded-xl transition-all">
620
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
621
- </button>
622
- </div>
623
-
624
- <div className="p-8 space-y-6">
625
- <div className="space-y-2">
626
- <label className="text-[10px] font-black text-armoyu-text-muted uppercase tracking-widest ml-4">SENİ TANIYALIM</label>
627
- <textarea
628
- className="w-full bg-black/10 border border-armoyu-card-border rounded-3xl px-6 py-5 text-sm font-bold text-armoyu-text focus:outline-none focus:border-blue-500 transition-all min-h-[150px] resize-none"
629
- placeholder="Örneğin: Merhaba! Ben bir ARMOYU üyesiyim ve oyun geliştirmeyi seviyorum..."
630
- value={tempBio}
631
- onChange={(e) => setTempBio(e.target.value)}
632
- autoFocus
633
- />
634
- </div>
635
-
636
- <button
637
- onClick={handleBioSave}
638
- className="w-full py-5 bg-blue-600 hover:bg-blue-500 text-white font-black rounded-[20px] text-xs uppercase tracking-widest shadow-xl shadow-blue-500/20 active:scale-95 transition-all flex items-center justify-center gap-2 italic"
639
- >
640
- BİYOGRAFİMİ KAYDET
641
- </button>
642
- </div>
643
- </div>
644
- </div>
645
- )}
646
- </div>
647
- );
648
- }
649
-