@armoyu/ui 1.0.1 → 1.0.2
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.
- package/dist/app/api/proxy/[...path]/route.d.ts +22 -0
- package/dist/app/api/proxy/[...path]/route.d.ts.map +1 -0
- package/dist/app/api/proxy/[...path]/route.js +89 -0
- package/dist/app/api/proxy/[...path]/route.js.map +1 -0
- package/dist/app/layout.d.ts.map +1 -1
- package/dist/app/layout.js +2 -5
- package/dist/app/layout.js.map +1 -1
- package/dist/components/RollingNumber.d.ts +6 -6
- package/dist/components/RollingNumber.js +23 -23
- package/dist/components/RollingNumber.js.map +1 -1
- package/dist/components/StatsGrid.d.ts +5 -5
- package/dist/components/modules/auth/Dashboard.d.ts +1 -1
- package/dist/components/modules/auth/PostCard.d.ts +24 -24
- package/dist/components/modules/auth/PostInteractionsModal.d.ts +11 -11
- package/dist/components/modules/auth/RepostModal.d.ts +21 -21
- package/dist/components/modules/auth/SidebarLeft.d.ts +1 -1
- package/dist/components/modules/auth/Stories.d.ts +1 -1
- package/dist/components/modules/auth/StoryViewer.d.ts +9 -9
- package/dist/components/modules/chat/ChatContainer.d.ts +1 -1
- package/dist/components/modules/chat/ChatInput.d.ts +4 -4
- package/dist/components/modules/chat/ChatList.d.ts +6 -6
- package/dist/components/modules/chat/ChatNotes.d.ts +1 -1
- package/dist/components/modules/community/GroupHeader.d.ts +10 -10
- package/dist/components/modules/community/GroupMenu.d.ts +9 -9
- package/dist/components/modules/community/SchoolCard.d.ts +6 -6
- package/dist/components/modules/community/SurveyCard.d.ts +6 -6
- package/dist/components/modules/guest/Introduction.d.ts +1 -1
- package/dist/components/modules/magaza/BackToStore.d.ts +1 -1
- package/dist/components/modules/magaza/StoreHeader.d.ts +5 -5
- package/dist/components/modules/news/NewsCard.d.ts +11 -11
- package/dist/components/modules/news/NewsComments.d.ts +1 -1
- package/dist/components/modules/profile/ProfileContent.d.ts +4 -4
- package/dist/components/modules/profile/ProfileHeader.d.ts +7 -7
- package/dist/components/modules/profile/ProfileStats.d.ts +1 -1
- package/dist/components/modules/profile/ProfileStats.js +14 -14
- package/dist/components/modules/profile/ProfileStats.js.map +1 -1
- package/dist/components/modules/profile/TeamSelectorModal.d.ts +10 -10
- package/dist/components/modules/stations/StationCard.d.ts +2 -2
- package/dist/components/modules/stations/StationQRModal.d.ts +9 -9
- package/dist/components/shared/FloatingChatButton.d.ts +4 -4
- package/dist/components/shared/Header.d.ts +1 -1
- package/dist/components/shared/LoginModal.d.ts +4 -4
- package/dist/components/shared/LoginModal.d.ts.map +1 -1
- package/dist/components/shared/LoginModal.js +65 -69
- package/dist/components/shared/LoginModal.js.map +1 -1
- package/dist/components/shared/MainLayoutWrapper.d.ts +3 -3
- package/dist/components/showcase/SocialTab.d.ts.map +1 -1
- package/dist/components/showcase/SocialTab.js +47 -2
- package/dist/components/showcase/SocialTab.js.map +1 -1
- package/dist/context/AuthContext.d.ts +18 -18
- package/dist/context/AuthContext.d.ts.map +1 -1
- package/dist/context/AuthContext.js +93 -74
- package/dist/context/AuthContext.js.map +1 -1
- package/dist/context/CartContext.d.ts +16 -16
- package/dist/context/SocketContext.d.ts +12 -12
- package/dist/index.d.ts +65 -65
- package/dist/lib/constants/educationData.d.ts +7 -7
- package/dist/lib/constants/seedData.d.ts +164 -164
- package/dist/lib/constants/stationData.d.ts +13 -13
- package/dist/lib/constants/surveyData.d.ts +2 -2
- package/dist/lib/constants/teamData.d.ts +12 -12
- package/package.json +13 -11
- package/next.config.ts +0 -13
- package/postcss.config.js +0 -6
- package/src/app/layout.tsx +0 -67
- package/src/app/page.tsx +0 -101
- package/src/components/Button.tsx +0 -41
- package/src/components/GenderStatsBar.tsx +0 -66
- package/src/components/RollingNumber.tsx +0 -50
- package/src/components/Slider.tsx +0 -114
- package/src/components/StatsGrid.tsx +0 -35
- package/src/components/ViewModeToggle.tsx +0 -39
- package/src/components/modules/auth/Dashboard.tsx +0 -649
- package/src/components/modules/auth/MediaLightbox.tsx +0 -112
- package/src/components/modules/auth/PostCard.tsx +0 -556
- package/src/components/modules/auth/PostInteractionsModal.tsx +0 -138
- package/src/components/modules/auth/RepostModal.tsx +0 -167
- package/src/components/modules/auth/SidebarLeft.tsx +0 -237
- package/src/components/modules/auth/Stories.tsx +0 -69
- package/src/components/modules/auth/StoryViewer.tsx +0 -146
- package/src/components/modules/chat/ChatContainer.tsx +0 -332
- package/src/components/modules/chat/ChatInput.tsx +0 -57
- package/src/components/modules/chat/ChatList.tsx +0 -179
- package/src/components/modules/chat/ChatMessage.tsx +0 -43
- package/src/components/modules/chat/ChatNotes.tsx +0 -58
- package/src/components/modules/community/GroupHeader.tsx +0 -111
- package/src/components/modules/community/GroupMenu.tsx +0 -82
- package/src/components/modules/community/SchoolCard.tsx +0 -104
- package/src/components/modules/community/SurveyCard.tsx +0 -149
- package/src/components/modules/forum/ForumBoard.tsx +0 -78
- package/src/components/modules/forum/ForumPost.tsx +0 -71
- package/src/components/modules/forum/NewTopicModal.tsx +0 -112
- package/src/components/modules/forum/TopicItem.tsx +0 -72
- package/src/components/modules/galleries/GalleryCard.tsx +0 -66
- package/src/components/modules/giveaways/GiveawayCard.tsx +0 -76
- package/src/components/modules/groups/ApplicationModal.tsx +0 -133
- package/src/components/modules/groups/GroupCard.tsx +0 -96
- package/src/components/modules/guest/Introduction.tsx +0 -60
- package/src/components/modules/magaza/BackToStore.tsx +0 -53
- package/src/components/modules/magaza/StoreHeader.tsx +0 -74
- package/src/components/modules/news/NewsCard.tsx +0 -66
- package/src/components/modules/news/NewsComments.tsx +0 -141
- package/src/components/modules/profile/CloudStorageModal.tsx +0 -200
- package/src/components/modules/profile/EditProfileModal.tsx +0 -191
- package/src/components/modules/profile/ProfileContent.tsx +0 -491
- package/src/components/modules/profile/ProfileHeader.tsx +0 -128
- package/src/components/modules/profile/ProfileStats.tsx +0 -72
- package/src/components/modules/profile/TeamSelectorModal.tsx +0 -129
- package/src/components/modules/stations/StationCard.tsx +0 -95
- package/src/components/modules/stations/StationQRModal.tsx +0 -102
- package/src/components/shared/FloatingChatButton.tsx +0 -57
- package/src/components/shared/Footer.tsx +0 -77
- package/src/components/shared/Header.tsx +0 -799
- package/src/components/shared/LoginModal.tsx +0 -208
- package/src/components/shared/MainLayoutWrapper.tsx +0 -15
- package/src/components/shared/PageWidth.tsx +0 -22
- package/src/components/showcase/CommunityTab.tsx +0 -22
- package/src/components/showcase/CorporateTab.tsx +0 -38
- package/src/components/showcase/GeneralTab.tsx +0 -41
- package/src/components/showcase/MessagesTab.tsx +0 -26
- package/src/components/showcase/ProfileTab.tsx +0 -20
- package/src/components/showcase/ShopTab.tsx +0 -24
- package/src/components/showcase/SocialTab.tsx +0 -28
- package/src/context/AuthContext.tsx +0 -104
- package/src/context/CartContext.tsx +0 -93
- package/src/context/ChatContext.tsx +0 -32
- package/src/context/LayoutContext.tsx +0 -29
- package/src/context/SocketContext.tsx +0 -50
- package/src/context/ThemeContext.tsx +0 -52
- package/src/index.ts +0 -96
- package/src/lib/constants/educationData.ts +0 -124
- package/src/lib/constants/punishmentData.ts +0 -201
- package/src/lib/constants/seedData.ts +0 -758
- package/src/lib/constants/stationData.ts +0 -170
- package/src/lib/constants/surveyData.ts +0 -53
- package/src/lib/constants/teamData.ts +0 -69
- package/src/lib/utils/numberFormat.ts +0 -16
- package/src/lib/utils/odpUtils.ts +0 -51
- package/src/types/index.ts +0 -1
- package/src/types/stats.ts +0 -17
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { Button } from '../Button';
|
|
5
|
-
import { useAuth } from '../../context/AuthContext';
|
|
6
|
-
import { userList } from '../../lib/constants/seedData';
|
|
7
|
-
|
|
8
|
-
export function LoginModal({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) {
|
|
9
|
-
const { login } = useAuth();
|
|
10
|
-
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
11
|
-
const [username, setUsername] = React.useState('');
|
|
12
|
-
const [password, setPassword] = React.useState('');
|
|
13
|
-
const [error, setError] = React.useState('');
|
|
14
|
-
|
|
15
|
-
// QR Kod State'leri
|
|
16
|
-
const [qrValue, setQrValue] = React.useState('');
|
|
17
|
-
const [qrProgress, setQrProgress] = React.useState(100);
|
|
18
|
-
|
|
19
|
-
// Modal açıldığında form verilerinin ve QR kodun yönetimi
|
|
20
|
-
React.useEffect(() => {
|
|
21
|
-
if (!isOpen) {
|
|
22
|
-
setUsername('');
|
|
23
|
-
setPassword('');
|
|
24
|
-
setError('');
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const generateQR = () => {
|
|
29
|
-
// Gerçek senaryoda bu veri backend'den dönen ve JWT içeren tek kullanımlık bir token olur.
|
|
30
|
-
setQrValue(`armoyu_mobile_auth_${Math.random().toString(36).substring(2, 15)}`);
|
|
31
|
-
setQrProgress(100);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
generateQR();
|
|
35
|
-
|
|
36
|
-
const refreshInterval = setInterval(() => {
|
|
37
|
-
generateQR();
|
|
38
|
-
}, 20000); // Her 20 saniyede bir yenilenir
|
|
39
|
-
|
|
40
|
-
const progressInterval = setInterval(() => {
|
|
41
|
-
// 20 saniyelik süreci 100 parçaya bölerek her 100ms'de azaltır
|
|
42
|
-
setQrProgress((prev) => Math.max(0, prev - (100 / (20000 / 100))));
|
|
43
|
-
}, 100);
|
|
44
|
-
|
|
45
|
-
return () => {
|
|
46
|
-
clearInterval(refreshInterval);
|
|
47
|
-
clearInterval(progressInterval);
|
|
48
|
-
};
|
|
49
|
-
}, [isOpen]);
|
|
50
|
-
|
|
51
|
-
if (!isOpen) return null;
|
|
52
|
-
|
|
53
|
-
const handleLogin = (e: React.FormEvent) => {
|
|
54
|
-
e.preventDefault();
|
|
55
|
-
setError('');
|
|
56
|
-
setIsSubmitting(true);
|
|
57
|
-
|
|
58
|
-
// Simulate API delay
|
|
59
|
-
setTimeout(() => {
|
|
60
|
-
// Search for the user in our seeded userList
|
|
61
|
-
const foundUser = userList.find((u: any) =>
|
|
62
|
-
u.username.toLowerCase() === username.toLowerCase()
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
if (foundUser) {
|
|
66
|
-
login(foundUser);
|
|
67
|
-
setIsSubmitting(false);
|
|
68
|
-
onClose();
|
|
69
|
-
} else {
|
|
70
|
-
setError('Kullanıcı bulunamadı! Lütfen listedeki geçerli bir kullanıcı adını deneyin.');
|
|
71
|
-
setIsSubmitting(false);
|
|
72
|
-
}
|
|
73
|
-
}, 800);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const fillTestAccount = () => {
|
|
77
|
-
setUsername('test');
|
|
78
|
-
setPassword('123456');
|
|
79
|
-
setError('');
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4 animate-in fade-in duration-200">
|
|
84
|
-
<div className="relative glass-panel bg-[#0a0a0e]/95 w-full max-w-4xl rounded-[2rem] shadow-[0_0_50px_rgba(0,0,0,1)] border border-white/10 flex flex-col md:flex-row overflow-hidden animate-in zoom-in-95 duration-300">
|
|
85
|
-
|
|
86
|
-
{/* Kapat butonu */}
|
|
87
|
-
<button
|
|
88
|
-
onClick={onClose}
|
|
89
|
-
className="absolute top-6 right-6 z-20 text-gray-400 hover:text-white transition-colors bg-white/5 p-2 rounded-full hover:bg-white/10 border border-white/5"
|
|
90
|
-
title="Kapat"
|
|
91
|
-
>
|
|
92
|
-
<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"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
|
93
|
-
</button>
|
|
94
|
-
|
|
95
|
-
{/* Klasik Giriş Alanı (Sol) */}
|
|
96
|
-
<div className="w-full md:w-1/2 p-8 lg:p-12 flex flex-col justify-center relative z-10">
|
|
97
|
-
|
|
98
|
-
<h2 className="text-3xl font-black mb-2 text-white tracking-tight">
|
|
99
|
-
Giriş Yap
|
|
100
|
-
</h2>
|
|
101
|
-
<p className="text-gray-400 text-sm mb-8">Kaldığın yerden oynamaya devam et.</p>
|
|
102
|
-
|
|
103
|
-
{/* Test Hesabı Asistanı */}
|
|
104
|
-
<div className="mb-6 p-4 bg-blue-500/10 border border-blue-500/20 rounded-xl text-center shadow-inner flex items-center justify-between gap-4">
|
|
105
|
-
<p className="text-xs text-blue-300 font-medium text-left">Test hesabı ile <br/>arayüzü inceleyin.</p>
|
|
106
|
-
<button
|
|
107
|
-
type="button"
|
|
108
|
-
onClick={() => { setUsername('berkaytikenoglu'); setPassword('armo-v3'); }}
|
|
109
|
-
className="text-xs font-bold bg-gradient-to-r from-blue-600 to-blue-500 hover:from-blue-500 hover:to-blue-400 text-white py-2 px-4 rounded-lg transition-all shadow-[0_0_10px_rgba(37,99,235,0.3)] border border-blue-400/50 whitespace-nowrap"
|
|
110
|
-
>
|
|
111
|
-
Kurucu Bilgilerini Gir
|
|
112
|
-
</button>
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
<form className="space-y-4" onSubmit={handleLogin}>
|
|
116
|
-
{error && (
|
|
117
|
-
<div className="p-3 bg-red-500/10 border border-red-500/30 text-red-400 text-sm font-medium rounded-xl text-center animate-in slide-in-from-top-2 duration-200">
|
|
118
|
-
{error}
|
|
119
|
-
</div>
|
|
120
|
-
)}
|
|
121
|
-
|
|
122
|
-
<div className="space-y-1.5">
|
|
123
|
-
<label className="text-xs font-bold text-gray-400 uppercase tracking-wider">Kullanıcı Adı</label>
|
|
124
|
-
<input
|
|
125
|
-
required
|
|
126
|
-
type="text"
|
|
127
|
-
value={username}
|
|
128
|
-
onChange={(e) => setUsername(e.target.value)}
|
|
129
|
-
className="w-full bg-white/5 border border-white/10 hover:border-white/20 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all font-medium"
|
|
130
|
-
placeholder="••••••"
|
|
131
|
-
/>
|
|
132
|
-
</div>
|
|
133
|
-
|
|
134
|
-
<div className="space-y-1.5">
|
|
135
|
-
<label className="text-xs font-bold text-gray-400 uppercase tracking-wider">Şifre</label>
|
|
136
|
-
<input
|
|
137
|
-
required
|
|
138
|
-
type="password"
|
|
139
|
-
value={password}
|
|
140
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
141
|
-
className="w-full bg-white/5 border border-white/10 hover:border-white/20 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all font-medium tracking-widest"
|
|
142
|
-
placeholder="••••••••"
|
|
143
|
-
/>
|
|
144
|
-
</div>
|
|
145
|
-
|
|
146
|
-
<div className="flex justify-between items-center text-sm px-1 pt-1">
|
|
147
|
-
<label className="flex items-center space-x-2 cursor-pointer text-gray-400 hover:text-gray-300">
|
|
148
|
-
<input type="checkbox" className="rounded bg-transparent border border-white/20 text-blue-500 focus:ring-blue-500 h-4 w-4" />
|
|
149
|
-
<span>Beni Hatırla</span>
|
|
150
|
-
</label>
|
|
151
|
-
<a href="#" className="text-blue-400 hover:text-blue-300 transition-colors font-medium">Şifremi Unuttum</a>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<Button variant="primary" className="w-full h-12 text-md mt-6 font-bold shadow-[0_0_15px_rgba(37,99,235,0.4)] rounded-xl" isLoading={isSubmitting}>
|
|
155
|
-
Hesabıma Giriş Yap
|
|
156
|
-
</Button>
|
|
157
|
-
|
|
158
|
-
<p className="text-center text-gray-500 text-sm mt-6 font-medium">
|
|
159
|
-
Henüz ARMOYU'da değil misin? <a href="#" className="text-blue-400 hover:text-blue-300 ml-1">Kayıt Ol</a>
|
|
160
|
-
</p>
|
|
161
|
-
</form>
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
|
-
{/* QR Kod Alanı (Sağ) */}
|
|
165
|
-
<div className="w-full md:w-1/2 bg-gradient-to-br from-[#0c101c] to-[#160b24] p-8 lg:p-12 flex flex-col items-center justify-center border-t md:border-t-0 md:border-l border-white/5 relative">
|
|
166
|
-
|
|
167
|
-
<div className="text-center space-y-4 mb-8 relative z-10 w-full">
|
|
168
|
-
<h3 className="text-2xl font-bold text-white tracking-tight">Mobil Uygulama İle Gir</h3>
|
|
169
|
-
<p className="text-gray-400 text-sm max-w-[260px] mx-auto leading-relaxed">
|
|
170
|
-
ARMOYU uygulamasından <strong className="text-white font-medium">Ayarlar > QR Okut</strong> menüsüne girerek saniyeler içinde bağlanın.
|
|
171
|
-
</p>
|
|
172
|
-
</div>
|
|
173
|
-
|
|
174
|
-
{/* QR Container */}
|
|
175
|
-
<div className="relative p-3 bg-white/10 backdrop-blur-md rounded-[2rem] shadow-2xl overflow-hidden border border-white/10">
|
|
176
|
-
<div className="bg-white p-4 rounded-2xl relative overflow-hidden group">
|
|
177
|
-
{/* QR Resim */}
|
|
178
|
-
<img
|
|
179
|
-
src={`https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=${qrValue}`}
|
|
180
|
-
alt="Login QR Code"
|
|
181
|
-
className="w-44 h-44 md:w-48 md:h-48 transition-all duration-300 group-hover:scale-105"
|
|
182
|
-
style={{ opacity: qrProgress > 95 ? 0.3 : 1 }}
|
|
183
|
-
/>
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
|
|
187
|
-
{/* Animasyonlu Timer */}
|
|
188
|
-
<div className="mt-10 flex flex-col items-center w-full max-w-[220px]">
|
|
189
|
-
<div className="w-full h-1.5 bg-white/10 rounded-full overflow-hidden shadow-inner">
|
|
190
|
-
<div
|
|
191
|
-
className="h-full bg-gradient-to-r from-blue-500 to-purple-500 rounded-full transition-all duration-100 ease-linear shadow-[0_0_10px_rgba(168,85,247,0.5)]"
|
|
192
|
-
style={{ width: `${qrProgress}%` }}
|
|
193
|
-
/>
|
|
194
|
-
</div>
|
|
195
|
-
<p className="text-xs text-gray-400 mt-3 font-medium flex items-center gap-1.5">
|
|
196
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" className={`${qrProgress < 15 ? 'text-red-400 animate-pulse' : 'text-blue-400'}`}><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>
|
|
197
|
-
<span className={`${qrProgress < 15 ? 'text-red-400' : 'text-gray-400'}`}>
|
|
198
|
-
{Math.ceil((qrProgress / 100) * 20)} saniye içinde yenilenecek
|
|
199
|
-
</span>
|
|
200
|
-
</p>
|
|
201
|
-
</div>
|
|
202
|
-
|
|
203
|
-
</div>
|
|
204
|
-
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
);
|
|
208
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useLayout } from '../../context/LayoutContext';
|
|
4
|
-
import { useAuth } from '../../context/AuthContext';
|
|
5
|
-
import { useSocket } from '../../context/SocketContext';
|
|
6
|
-
|
|
7
|
-
export function MainLayoutWrapper({ children }: { children: React.ReactNode }) {
|
|
8
|
-
const { pageWidth } = useLayout();
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<main className={`flex-grow w-full overflow-x-hidden pt-8 px-4 md:px-8 mx-auto z-10 transition-all duration-700 ${pageWidth}`}>
|
|
12
|
-
{children}
|
|
13
|
-
</main>
|
|
14
|
-
);
|
|
15
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useEffect } from 'react';
|
|
4
|
-
import { useLayout } from '../../context/LayoutContext';
|
|
5
|
-
|
|
6
|
-
interface PageWidthProps {
|
|
7
|
-
width: string; // Örn: 'max-w-7xl', 'max-w-full', 'max-w-[90%]'
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function PageWidth({ width }: PageWidthProps) {
|
|
11
|
-
const { setPageWidth } = useLayout();
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
// Sayfa yüklendiğinde yeni genişliği uygula
|
|
15
|
-
setPageWidth(width);
|
|
16
|
-
|
|
17
|
-
// Sayfadan çıkıldığında varsayılan değere (%80) geri dön
|
|
18
|
-
return () => setPageWidth('max-w-[80%]');
|
|
19
|
-
}, [width, setPageWidth]);
|
|
20
|
-
|
|
21
|
-
return null; // Görünür bir element üretmez
|
|
22
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ForumBoard,
|
|
4
|
-
GroupCard,
|
|
5
|
-
groupList,
|
|
6
|
-
MOCK_FORUM_CATEGORIES
|
|
7
|
-
} from '../../index';
|
|
8
|
-
|
|
9
|
-
export function CommunityTab() {
|
|
10
|
-
return (
|
|
11
|
-
<div className="space-y-12">
|
|
12
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-orange-500 pl-4">Topluluk & Forum</h3>
|
|
13
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
14
|
-
<div className="md:col-span-2">
|
|
15
|
-
<ForumBoard {...MOCK_FORUM_CATEGORIES[1].boards[0]} />
|
|
16
|
-
</div>
|
|
17
|
-
<GroupCard {...groupList[0]} />
|
|
18
|
-
<GroupCard {...groupList[1]} />
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Header,
|
|
4
|
-
Footer,
|
|
5
|
-
ViewModeToggle
|
|
6
|
-
} from '../../index';
|
|
7
|
-
|
|
8
|
-
export function CorporateTab() {
|
|
9
|
-
return (
|
|
10
|
-
<div className="space-y-16">
|
|
11
|
-
<div className="space-y-6">
|
|
12
|
-
<div className="flex items-center justify-between">
|
|
13
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-indigo-500 pl-4">Header Bileşeni</h3>
|
|
14
|
-
<span className="text-[10px] font-bold text-armoyu-text-muted uppercase italic bg-black/20 px-3 py-1 rounded-lg">Kütüphane Bileşeni Önizleme</span>
|
|
15
|
-
</div>
|
|
16
|
-
<div className="rounded-[32px] overflow-hidden border border-white/5 shadow-2xl relative">
|
|
17
|
-
<Header />
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<div className="space-y-6">
|
|
22
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-indigo-500 pl-4">Footer Bileşeni</h3>
|
|
23
|
-
<div className="rounded-[32px] overflow-hidden border border-white/5 shadow-2xl">
|
|
24
|
-
<Footer />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-8">
|
|
29
|
-
<div className="glass-panel p-8 rounded-[40px]">
|
|
30
|
-
<h4 className="text-[10px] font-black uppercase text-center mb-6 opacity-30 italic">Görünüm Seçici</h4>
|
|
31
|
-
<div className="flex justify-center">
|
|
32
|
-
<ViewModeToggle mode="grid" onChange={() => {}} />
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Button,
|
|
4
|
-
RollingNumber,
|
|
5
|
-
Slider,
|
|
6
|
-
StatsGrid,
|
|
7
|
-
mockGlobalStats
|
|
8
|
-
} from '../../index';
|
|
9
|
-
|
|
10
|
-
export function GeneralTab() {
|
|
11
|
-
return (
|
|
12
|
-
<div className="space-y-12">
|
|
13
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-blue-500 pl-4">Temel Bileşenler</h3>
|
|
14
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
15
|
-
<div className="glass-panel p-8 rounded-[40px] space-y-6">
|
|
16
|
-
<h4 className="text-xs font-black uppercase tracking-widest text-armoyu-text-muted mb-4 opacity-50 italic">Butonlar</h4>
|
|
17
|
-
<div className="flex flex-wrap gap-4">
|
|
18
|
-
<Button>Normal Buton</Button>
|
|
19
|
-
<Button variant="ghost">Hayalet Buton</Button>
|
|
20
|
-
<Button className="bg-gradient-to-r from-blue-600 to-indigo-600">Premium Buton</Button>
|
|
21
|
-
<Button className="bg-emerald-500">Başarı</Button>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
<div className="glass-panel p-8 rounded-[40px] space-y-6">
|
|
25
|
-
<h4 className="text-xs font-black uppercase tracking-widest text-armoyu-text-muted mb-4 opacity-50 italic">Sayı Animasyonları</h4>
|
|
26
|
-
<div className="flex items-center gap-8">
|
|
27
|
-
<div className="text-4xl font-black text-blue-500 italic"><RollingNumber value="14.2" />B</div>
|
|
28
|
-
<div className="text-3xl font-black text-armoyu-text italic opacity-60"><RollingNumber value="1250" /></div>
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
<div className="glass-panel p-8 rounded-[40px] space-y-6 md:col-span-2">
|
|
32
|
-
<h4 className="text-xs font-black uppercase tracking-widest text-armoyu-text-muted mb-4 opacity-50 italic">Slider / Carousel</h4>
|
|
33
|
-
<Slider />
|
|
34
|
-
</div>
|
|
35
|
-
<div className="md:col-span-2">
|
|
36
|
-
<StatsGrid stats={mockGlobalStats} />
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ChatNotes,
|
|
4
|
-
ChatList,
|
|
5
|
-
ChatContainer,
|
|
6
|
-
MOCK_SESSION
|
|
7
|
-
} from '../../index';
|
|
8
|
-
|
|
9
|
-
export function MessagesTab() {
|
|
10
|
-
return (
|
|
11
|
-
<div className="space-y-12">
|
|
12
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-emerald-500 pl-4">Mesajlaşma Sistemi</h3>
|
|
13
|
-
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 h-[700px]">
|
|
14
|
-
<div className="lg:col-span-4 glass-panel rounded-[40px] overflow-hidden flex flex-col">
|
|
15
|
-
<ChatNotes />
|
|
16
|
-
<div className="flex-1 overflow-hidden p-2">
|
|
17
|
-
<ChatList contacts={MOCK_SESSION.chatList} activeId="c1" onSelect={() => {}} />
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
<div className="lg:col-span-8 glass-panel rounded-[40px] overflow-hidden">
|
|
21
|
-
<ChatContainer />
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ProfileHeader,
|
|
4
|
-
ProfileStats,
|
|
5
|
-
ProfileContent,
|
|
6
|
-
userList
|
|
7
|
-
} from '../../index';
|
|
8
|
-
|
|
9
|
-
export function ProfileTab() {
|
|
10
|
-
const me = userList[0];
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="space-y-12">
|
|
14
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-pink-500 pl-4">Kullanıcı Profili</h3>
|
|
15
|
-
<ProfileHeader user={me} isOwnProfile={true} />
|
|
16
|
-
<ProfileStats />
|
|
17
|
-
<ProfileContent user={me} />
|
|
18
|
-
</div>
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
StoreHeader,
|
|
4
|
-
NewsCard,
|
|
5
|
-
newsList
|
|
6
|
-
} from '../../index';
|
|
7
|
-
|
|
8
|
-
export function ShopTab() {
|
|
9
|
-
return (
|
|
10
|
-
<div className="space-y-12">
|
|
11
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-yellow-500 pl-4">Mağaza & İçerik</h3>
|
|
12
|
-
<div className="space-y-8">
|
|
13
|
-
<div className="glass-panel p-6 rounded-[32px]">
|
|
14
|
-
<StoreHeader searchQuery="" setSearchQuery={() => {}} />
|
|
15
|
-
</div>
|
|
16
|
-
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
17
|
-
{newsList.map(news => (
|
|
18
|
-
<NewsCard key={news.slug} {...news} />
|
|
19
|
-
))}
|
|
20
|
-
</div>
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
AuthSidebarLeft,
|
|
4
|
-
Stories,
|
|
5
|
-
PostCard,
|
|
6
|
-
postList
|
|
7
|
-
} from '../../index';
|
|
8
|
-
|
|
9
|
-
export function SocialTab() {
|
|
10
|
-
const samplePosts = postList.slice(0, 3);
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="space-y-12">
|
|
14
|
-
<h3 className="text-2xl font-black italic uppercase tracking-tighter border-l-4 border-purple-500 pl-4">Sosyal Modüller</h3>
|
|
15
|
-
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
|
16
|
-
<aside className="lg:col-span-3">
|
|
17
|
-
<AuthSidebarLeft />
|
|
18
|
-
</aside>
|
|
19
|
-
<div className="lg:col-span-9 space-y-8">
|
|
20
|
-
<Stories />
|
|
21
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
22
|
-
{samplePosts.map(post => <PostCard key={post.id} {...post} />)}
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
4
|
-
import { User, Session } from '@armoyu/core';
|
|
5
|
-
|
|
6
|
-
import { userList, MOCK_SESSION } from '../lib/constants/seedData';
|
|
7
|
-
|
|
8
|
-
interface AuthContextType {
|
|
9
|
-
user: User | null;
|
|
10
|
-
session: Session | null;
|
|
11
|
-
login: (userData: User) => void;
|
|
12
|
-
logout: () => void;
|
|
13
|
-
isLoading: boolean;
|
|
14
|
-
isLoginModalOpen: boolean;
|
|
15
|
-
setIsLoginModalOpen: (open: boolean) => void;
|
|
16
|
-
updateUser: (updatedUser: User) => void;
|
|
17
|
-
updateSession: (updatedSession: Session) => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|
21
|
-
|
|
22
|
-
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
23
|
-
const [user, setUser] = useState<User | null>(null);
|
|
24
|
-
const [session, setSession] = useState<Session | null>(null);
|
|
25
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
26
|
-
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
// Check local storage for persistent login
|
|
30
|
-
const savedUserStr = localStorage.getItem('armoyu_user');
|
|
31
|
-
|
|
32
|
-
if (savedUserStr) {
|
|
33
|
-
try {
|
|
34
|
-
const savedData = JSON.parse(savedUserStr);
|
|
35
|
-
const username = savedData.username;
|
|
36
|
-
|
|
37
|
-
// Find user in seedData to maintain all object references
|
|
38
|
-
const foundUser = userList.find((u: any) => u.username === username);
|
|
39
|
-
|
|
40
|
-
if (foundUser) {
|
|
41
|
-
setUser(foundUser);
|
|
42
|
-
// If it's Berkay, use the mock session with notifications
|
|
43
|
-
if (username === 'berkaytikenoglu') {
|
|
44
|
-
setSession(MOCK_SESSION);
|
|
45
|
-
} else {
|
|
46
|
-
setSession(new Session({ user: foundUser, token: 'mock-token' }));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} catch (e) {
|
|
50
|
-
console.error('Failed to restore session', e);
|
|
51
|
-
localStorage.removeItem('armoyu_user');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Explicitly set loading to false AFTER the check
|
|
56
|
-
setIsLoading(false);
|
|
57
|
-
}, []);
|
|
58
|
-
|
|
59
|
-
const login = (userData: User) => {
|
|
60
|
-
setUser(userData);
|
|
61
|
-
|
|
62
|
-
// Handle session initialization
|
|
63
|
-
if (userData.username === 'berkaytikenoglu') {
|
|
64
|
-
setSession(MOCK_SESSION);
|
|
65
|
-
} else {
|
|
66
|
-
setSession(new Session({ user: userData, token: 'mock-token' }));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
localStorage.setItem('armoyu_user', JSON.stringify({ username: userData.username }));
|
|
70
|
-
setIsLoginModalOpen(false); // Close modal on success
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const logout = () => {
|
|
74
|
-
setUser(null);
|
|
75
|
-
setSession(null);
|
|
76
|
-
localStorage.removeItem('armoyu_user');
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const updateUser = (updatedUser: User) => {
|
|
80
|
-
setUser(updatedUser);
|
|
81
|
-
if (session) {
|
|
82
|
-
setSession(new Session({ ...session, user: updatedUser }));
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const updateSession = (updatedSession: Session) => {
|
|
87
|
-
setSession(updatedSession);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<AuthContext.Provider value={{ user, session, login, logout, isLoading, isLoginModalOpen, setIsLoginModalOpen, updateUser, updateSession }}>
|
|
92
|
-
{children}
|
|
93
|
-
</AuthContext.Provider>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function useAuth() {
|
|
98
|
-
const context = useContext(AuthContext);
|
|
99
|
-
if (context === undefined) {
|
|
100
|
-
throw new Error('useAuth must be used within an AuthProvider');
|
|
101
|
-
}
|
|
102
|
-
return context;
|
|
103
|
-
}
|
|
104
|
-
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
4
|
-
import { Product, CartItem } from '@armoyu/core';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface CartContextType {
|
|
8
|
-
cart: CartItem[];
|
|
9
|
-
addToCart: (product: Product, quantity?: number) => void;
|
|
10
|
-
removeFromCart: (productId: string) => void;
|
|
11
|
-
updateQuantity: (productId: string, quantity: number) => void;
|
|
12
|
-
clearCart: () => void;
|
|
13
|
-
totalItems: number;
|
|
14
|
-
totalPrice: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const CartContext = createContext<CartContextType | undefined>(undefined);
|
|
18
|
-
|
|
19
|
-
export function CartProvider({ children }: { children: React.ReactNode }) {
|
|
20
|
-
const [cart, setCart] = useState<CartItem[]>([]);
|
|
21
|
-
|
|
22
|
-
// Load cart from localStorage on mount
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
const savedCart = localStorage.getItem('armoyu_cart');
|
|
25
|
-
if (savedCart) {
|
|
26
|
-
try {
|
|
27
|
-
const parsed = JSON.parse(savedCart);
|
|
28
|
-
setCart(parsed.map((i: any) => CartItem.fromJSON(i)));
|
|
29
|
-
} catch (e) {
|
|
30
|
-
console.error('Failed to parse cart', e);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}, []);
|
|
34
|
-
|
|
35
|
-
// Save cart to localStorage on change
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
localStorage.setItem('armoyu_cart', JSON.stringify(cart));
|
|
38
|
-
}, [cart]);
|
|
39
|
-
|
|
40
|
-
const addToCart = (product: Product, quantity: number = 1) => {
|
|
41
|
-
setCart(prev => {
|
|
42
|
-
const existing = prev.find(item => item.product.id === product.id);
|
|
43
|
-
if (existing) {
|
|
44
|
-
return prev.map(item =>
|
|
45
|
-
item.product.id === product.id
|
|
46
|
-
? new CartItem({ ...item, quantity: item.quantity + quantity })
|
|
47
|
-
: item
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
return [...prev, new CartItem({ product, quantity })];
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const removeFromCart = (productId: string) => {
|
|
55
|
-
setCart(prev => prev.filter(item => item.product.id !== productId));
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const updateQuantity = (productId: string, quantity: number) => {
|
|
59
|
-
setCart(prev => prev.map(item =>
|
|
60
|
-
item.product.id === productId
|
|
61
|
-
? new CartItem({ ...item, quantity: Math.max(1, quantity) })
|
|
62
|
-
: item
|
|
63
|
-
));
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const clearCart = () => setCart([]);
|
|
67
|
-
|
|
68
|
-
const totalItems = cart.reduce((acc, item) => acc + item.quantity, 0);
|
|
69
|
-
const totalPrice = cart.reduce((acc, item) => acc + item.getTotalPrice(), 0);
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<CartContext.Provider value={{
|
|
73
|
-
cart,
|
|
74
|
-
addToCart,
|
|
75
|
-
removeFromCart,
|
|
76
|
-
updateQuantity,
|
|
77
|
-
clearCart,
|
|
78
|
-
totalItems,
|
|
79
|
-
totalPrice
|
|
80
|
-
}}>
|
|
81
|
-
{children}
|
|
82
|
-
</CartContext.Provider>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function useCart() {
|
|
87
|
-
const context = useContext(CartContext);
|
|
88
|
-
if (context === undefined) {
|
|
89
|
-
throw new Error('useCart must be used within a CartProvider');
|
|
90
|
-
}
|
|
91
|
-
return context;
|
|
92
|
-
}
|
|
93
|
-
|