dungvudoan commited on
Commit
3a910a6
·
verified ·
1 Parent(s): 3ce0a27

Upload 7 files

Browse files
Files changed (7) hide show
  1. README.md +70 -3
  2. index.html +321 -0
  3. prompts.txt +2 -0
  4. story_player_code.txt +237 -0
  5. style.css +28 -0
  6. upload.html +217 -0
  7. videos.js +165 -0
README.md CHANGED
@@ -1,3 +1,70 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: new3
3
+ emoji: 🐳
4
+ colorFrom: green
5
+ colorTo: gray
6
+ sdk: static
7
+ pinned: false
8
+ tags:
9
+ - deepsite
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+
14
+ # Kho truyện Mã A Lềnh - Video Story Player
15
+
16
+ A beautiful story player system for displaying and playing Vietnamese folk stories with video support.
17
+
18
+ ## Features
19
+
20
+ - Responsive design that works on desktop and mobile devices
21
+ - Beautiful card-based interface for browsing stories
22
+ - Video playback support with modal player
23
+ - Favorites system that persists between sessions (using localStorage)
24
+ - Filtering by story type
25
+
26
+ ## Setup Instructions
27
+
28
+ ### 1. Place your video files
29
+
30
+ Add your video files to the `videos` directory. The system is configured to use the following files:
31
+
32
+ - `videos/chuyen-con-suoi-muong-tien.mp4` - Story 1: Chuyện con suối Mường Tiên
33
+ - `videos/chiec-banh-trong-day-tui.mp4` - Story 2: Chiếc bánh trong đẩy túi
34
+ - `videos/vung-dam-cua-than-rong.mp4` - Story 3: Vũng đầm của thần rồng
35
+
36
+ ### 2. Customize (Optional)
37
+
38
+ If you want to use different video files or paths:
39
+
40
+ 1. Open `videos.js`
41
+ 2. Modify the `videoSources` object to point to your video files
42
+
43
+ ```javascript
44
+ const videoSources = {
45
+ 1: "your/custom/path/to/video1.mp4",
46
+ 2: "your/custom/path/to/video2.mp4",
47
+ 3: "your/custom/path/to/video3.mp4",
48
+ };
49
+ ```
50
+
51
+ ### 3. Launch the website
52
+
53
+ Open `index.html` in your web browser or deploy it to your web server.
54
+
55
+ ## Adding More Stories
56
+
57
+ To add additional stories:
58
+
59
+ 1. Duplicate one of the existing story card sections in `index.html`
60
+ 2. Update the content (image, title, description, duration)
61
+ 3. Update the `data-story` attribute to a new unique number
62
+ 4. Add the corresponding video source in `videos.js`
63
+
64
+ ## Technologies Used
65
+
66
+ - HTML5
67
+ - CSS3 (with Tailwind CSS)
68
+ - JavaScript
69
+ - Font Awesome for icons
70
+ - Google Fonts
index.html ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Kho truyện Mã A Lềnh</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link
9
+ rel="stylesheet"
10
+ href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
11
+ />
12
+ <link
13
+ href="https://fonts.googleapis.com/css2?family=Noto+Serif:wght@400;700&display=swap"
14
+ rel="stylesheet"
15
+ />
16
+ <link rel="stylesheet" href="style.css" />
17
+ <style>
18
+ body {
19
+ font-family: "Noto Serif", serif;
20
+ background-color: #fff9f0;
21
+ }
22
+ .story-card {
23
+ transition: all 0.3s ease;
24
+ transform: translateY(0);
25
+ }
26
+ .story-card:hover {
27
+ transform: translateY(-5px);
28
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
29
+ }
30
+ .story-card:hover .play-overlay {
31
+ opacity: 1;
32
+ }
33
+ .play-overlay {
34
+ transition: opacity 0.3s ease;
35
+ }
36
+ .fade-in {
37
+ animation: fadeIn 0.5s ease-in-out;
38
+ }
39
+ @keyframes fadeIn {
40
+ from {
41
+ opacity: 0;
42
+ transform: translateY(10px);
43
+ }
44
+ to {
45
+ opacity: 1;
46
+ transform: translateY(0);
47
+ }
48
+ }
49
+ .progress-bar {
50
+ height: 6px;
51
+ background-color: #ede9e3;
52
+ border-radius: 3px;
53
+ }
54
+ .progress-fill {
55
+ height: 100%;
56
+ background: linear-gradient(90deg, #d4a373 0%, #a18072 100%);
57
+ border-radius: 3px;
58
+ transition: width 0.1s linear;
59
+ }
60
+ .story-tag {
61
+ position: absolute;
62
+ top: 12px;
63
+ left: 12px;
64
+ color: white;
65
+ padding: 4px 8px;
66
+ border-radius: 4px;
67
+ font-size: 12px;
68
+ font-weight: bold;
69
+ }
70
+ .tag-children {
71
+ background-color: rgba(74, 222, 128, 0.9);
72
+ }
73
+ .tag-journal {
74
+ background-color: rgba(59, 130, 246, 0.9);
75
+ }
76
+ .video-container {
77
+ position: relative;
78
+ width: 100%;
79
+ height: 0;
80
+ padding-bottom: 56.25%; /* 16:9 aspect ratio */
81
+ }
82
+ .video-player {
83
+ position: absolute;
84
+ top: 0;
85
+ left: 0;
86
+ width: 100%;
87
+ height: 100%;
88
+ background-color: #000;
89
+ }
90
+ .video-controls {
91
+ position: absolute;
92
+ bottom: 0;
93
+ left: 0;
94
+ right: 0;
95
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
96
+ padding: 10px;
97
+ display: flex;
98
+ flex-direction: column;
99
+ opacity: 0;
100
+ transition: opacity 0.3s;
101
+ }
102
+ .video-container:hover .video-controls {
103
+ opacity: 1;
104
+ }
105
+ </style>
106
+ </head>
107
+ <body class="bg-amber-50">
108
+ <div class="container mx-auto px-4 py-8 max-w-7xl">
109
+ <!-- Header -->
110
+ <header
111
+ class="flex flex-col md:flex-row justify-between items-center mb-12"
112
+ >
113
+ <div class="flex items-center mb-4 md:mb-0">
114
+ <div class="bg-amber-700 text-white p-3 rounded-lg mr-4">
115
+ <i class="fas fa-book-open text-2xl"></i>
116
+ </div>
117
+ <h1 class="text-4xl font-bold text-amber-900">
118
+ Kho truyện Mã A Lềnh
119
+ </h1>
120
+ </div>
121
+ <div class="flex space-x-2">
122
+ <div class="bg-amber-100 p-2 rounded-full shadow-inner">
123
+ <button
124
+ id="all-stories-btn"
125
+ class="px-6 py-2 bg-amber-700 text-white rounded-full hover:bg-amber-800 transition-all duration-300 flex items-center"
126
+ >
127
+ <i class="fas fa-book mr-2"></i>
128
+ <span>Tất cả truyện</span>
129
+ </button>
130
+ <button
131
+ id="favorites-btn"
132
+ class="px-6 py-2 rounded-full hover:bg-amber-200 transition-all duration-300 flex items-center"
133
+ >
134
+ <i class="fas fa-heart mr-2 text-amber-700"></i>
135
+ <span>Yêu thích</span>
136
+ </button>
137
+ </div>
138
+ <a
139
+ href="upload.html"
140
+ class="flex items-center justify-center px-4 py-2 bg-amber-600 text-white rounded-full hover:bg-amber-700 transition-all duration-300"
141
+ >
142
+ <i class="fas fa-upload mr-2"></i>
143
+ <span>Upload</span>
144
+ </a>
145
+ </div>
146
+ </header>
147
+
148
+ <!-- Main Content -->
149
+ <main>
150
+ <!-- Stories Section -->
151
+ <section id="all-stories" class="fade-in">
152
+ <div
153
+ class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 justify-items-center"
154
+ >
155
+ <!-- Story Card 1 -->
156
+ <div
157
+ class="story-card bg-white rounded-xl shadow-lg overflow-hidden relative w-full max-w-sm"
158
+ >
159
+ <div class="relative">
160
+ <img
161
+ src="https://i.imgur.com/nsjKQ2G.jpeg"
162
+ alt="Chuyện con suối Mường Tiên"
163
+ class="w-full h-64 object-cover"
164
+ />
165
+ <div class="story-tag tag-children">Văn học thiếu nhi</div>
166
+ <div
167
+ class="play-overlay absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center opacity-0 transition-opacity"
168
+ >
169
+ <button class="play-btn" data-story="1">
170
+ <div
171
+ class="bg-white bg-opacity-30 rounded-full p-4 hover:bg-opacity-50 transition"
172
+ >
173
+ <i class="fas fa-play text-white text-3xl"></i>
174
+ </div>
175
+ </button>
176
+ </div>
177
+ </div>
178
+ <div class="p-6">
179
+ <h3 class="text-xl font-bold mb-3 text-amber-900 text-center">
180
+ Chuyện con suối Mường Tiên
181
+ </h3>
182
+ <p class="text-amber-800 mb-4 text-sm text-center">
183
+ Câu chuyện về Chà, cậu bé lớn lên bên suối Mường Tiên. Khi
184
+ suối bị chặn lại để xây thủy điện, Chà quyết tâm học giỏi để
185
+ cứu suối, phản ánh sự gắn bó giữa con người và thiên nhiên.
186
+ </p>
187
+ <div class="flex justify-between items-center">
188
+ <div class="flex items-center text-sm text-amber-700">
189
+ <i class="fas fa-clock mr-2"></i>
190
+ <span>1:18 phút</span>
191
+ </div>
192
+ <button class="favorite-btn" data-story="1">
193
+ <i
194
+ class="far fa-heart text-xl text-amber-600 hover:text-red-500 transition"
195
+ ></i>
196
+ </button>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ <!-- Story Card 2 -->
202
+ <div
203
+ class="story-card bg-white rounded-xl shadow-lg overflow-hidden relative w-full max-w-sm"
204
+ >
205
+ <div class="relative">
206
+ <img
207
+ src="https://i.imgur.com/5sZGRmA.jpeg"
208
+ alt="Chiếc bánh trong đẩy túi"
209
+ class="w-full h-64 object-cover"
210
+ />
211
+ <div class="story-tag tag-children">Văn học thiếu nhi</div>
212
+ <div
213
+ class="play-overlay absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center opacity-0 transition-opacity"
214
+ >
215
+ <button class="play-btn" data-story="2">
216
+ <div
217
+ class="bg-white bg-opacity-30 rounded-full p-4 hover:bg-opacity-50 transition"
218
+ >
219
+ <i class="fas fa-play text-white text-3xl"></i>
220
+ </div>
221
+ </button>
222
+ </div>
223
+ </div>
224
+ <div class="p-6">
225
+ <h3 class="text-xl font-bold mb-3 text-amber-900 text-center">
226
+ Chiếc bánh trong đẩy túi
227
+ </h3>
228
+ <p class="text-amber-800 mb-4 text-sm text-center">
229
+ Câu chuyện về Thạch Sơn, cậu bé sống trong vùng núi. Sau khi
230
+ mẹ mất, cậu luôn nhớ mẹ qua những chiếc bánh pa nếp. Mỗi dịp
231
+ Tết, cậu làm bánh cùng mẹ và các bác tiên tổ, giữ lại những ký
232
+ ức về mẹ suốt đời.
233
+ </p>
234
+ <div class="flex justify-between items-center">
235
+ <div class="flex items-center text-sm text-amber-700">
236
+ <i class="fas fa-clock mr-2"></i>
237
+ <span>20 phút</span>
238
+ </div>
239
+ <button class="favorite-btn" data-story="2">
240
+ <i
241
+ class="far fa-heart text-xl text-amber-600 hover:text-red-500 transition"
242
+ ></i>
243
+ </button>
244
+ </div>
245
+ </div>
246
+ </div>
247
+
248
+ <!-- Story Card 3 -->
249
+ <div
250
+ class="story-card bg-white rounded-xl shadow-lg overflow-hidden relative w-full max-w-sm"
251
+ >
252
+ <div class="relative">
253
+ <img
254
+ src="https://i.imgur.com/mH1KPtZ.jpeg"
255
+ alt="Vũng đầm của thần rồng"
256
+ class="w-full h-64 object-cover"
257
+ />
258
+ <div class="story-tag tag-journal">Ký sự</div>
259
+ <div
260
+ class="play-overlay absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center opacity-0 transition-opacity"
261
+ >
262
+ <button class="play-btn" data-story="3">
263
+ <div
264
+ class="bg-white bg-opacity-30 rounded-full p-4 hover:bg-opacity-50 transition"
265
+ >
266
+ <i class="fas fa-play text-white text-3xl"></i>
267
+ </div>
268
+ </button>
269
+ </div>
270
+ </div>
271
+ <div class="p-6">
272
+ <h3 class="text-xl font-bold mb-3 text-amber-900 text-center">
273
+ Vũng đầm của thần rồng
274
+ </h3>
275
+ <p class="text-amber-800 mb-4 text-sm text-center">
276
+ Chàng Rồng biến thành ngựa rồng, giúp dân có nước. Cô gái mở
277
+ cối yêu anh và họ có mối quan hệ. Khi ông Trời phát hiện,
278
+ chàng Rồng bỏ chạy, làm cạn hồ nước. Cô gái sống cô đơn và chờ
279
+ đợi anh suốt đời.
280
+ </p>
281
+ <div class="flex justify-between items-center">
282
+ <div class="flex items-center text-sm text-amber-700">
283
+ <i class="fas fa-clock mr-2"></i>
284
+ <span>12 phút</span>
285
+ </div>
286
+ <button class="favorite-btn" data-story="3">
287
+ <i
288
+ class="far fa-heart text-xl text-amber-600 hover:text-red-500 transition"
289
+ ></i>
290
+ </button>
291
+ </div>
292
+ </div>
293
+ </div>
294
+ </div>
295
+ </section>
296
+
297
+ <!-- Video Player Modal -->
298
+ <div
299
+ id="video-modal"
300
+ class="fixed inset-0 bg-black bg-opacity-75 hidden items-center justify-center z-50"
301
+ >
302
+ <div class="relative w-full max-w-5xl p-4">
303
+ <button
304
+ id="close-modal"
305
+ class="absolute top-0 right-0 -mt-10 -mr-10 text-white hover:text-amber-500 z-10"
306
+ >
307
+ <i class="fas fa-times text-2xl"></i>
308
+ </button>
309
+ <div class="video-container bg-black rounded-lg overflow-hidden">
310
+ <video id="video-player" class="video-player" controls>
311
+ Your browser does not support the video tag.
312
+ </video>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </main>
317
+ </div>
318
+
319
+ <script src="videos.js"></script>
320
+ </body>
321
+ </html>
prompts.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ thêm audio cho câu chuyện bên trong các story card
2
+ tôi muốn thêm adio vào phần bên trong các story card
story_player_code.txt ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="vi">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Kho truyện Mã A Lềnh</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <link href="https://fonts.googleapis.com/css2?family=Noto+Serif:wght@400;700&display=swap" rel="stylesheet">
11
+ <style>
12
+ body {
13
+ font-family: 'Noto Serif', serif;
14
+ background-color: #FFF9F0;
15
+ }
16
+ .story-card {
17
+ transition: all 0.3s ease;
18
+ transform: translateY(0);
19
+ }
20
+ .story-card:hover {
21
+ transform: translateY(-5px);
22
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
23
+ }
24
+ .story-card:hover .play-overlay {
25
+ opacity: 1;
26
+ }
27
+ .play-overlay {
28
+ transition: opacity 0.3s ease;
29
+ }
30
+ .fade-in {
31
+ animation: fadeIn 0.5s ease-in-out;
32
+ }
33
+ @keyframes fadeIn {
34
+ from { opacity: 0; transform: translateY(10px); }
35
+ to { opacity: 1; transform: translateY(0); }
36
+ }
37
+ .progress-bar {
38
+ height: 6px;
39
+ background-color: #EDE9E3;
40
+ border-radius: 3px;
41
+ }
42
+ .progress-fill {
43
+ height: 100%;
44
+ background: linear-gradient(90deg, #D4A373 0%, #A18072 100%);
45
+ border-radius: 3px;
46
+ transition: width 0.1s linear;
47
+ }
48
+ .story-tag {
49
+ position: absolute;
50
+ top: 12px;
51
+ left: 12px;
52
+ color: white;
53
+ padding: 4px 8px;
54
+ border-radius: 4px;
55
+ font-size: 12px;
56
+ font-weight: bold;
57
+ }
58
+ .tag-children {
59
+ background-color: rgba(74, 222, 128, 0.9);
60
+ }
61
+ .tag-journal {
62
+ background-color: rgba(59, 130, 246, 0.9);
63
+ }
64
+ .audio-wave {
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: space-between;
68
+ width: 60px;
69
+ height: 30px;
70
+ }
71
+ .wave-bar {
72
+ width: 4px;
73
+ background-color: #D4A373;
74
+ border-radius: 2px;
75
+ animation: wave 1.2s infinite ease-in-out;
76
+ }
77
+ .wave-bar:nth-child(1) { height: 8px; animation-delay: 0.1s; }
78
+ .wave-bar:nth-child(2) { height: 12px; animation-delay: 0.3s; }
79
+ .wave-bar:nth-child(3) { height: 16px; animation-delay: 0.5s; }
80
+ .wave-bar:nth-child(4) { height: 12px; animation-delay: 0.7s; }
81
+ .wave-bar:nth-child(5) { height: 8px; animation-delay: 0.9s; }
82
+ @keyframes wave {
83
+ 0%, 100% { transform: scaleY(0.8); }
84
+ 50% { transform: scaleY(1.5); }
85
+ }
86
+ .bookmark-icon {
87
+ position: absolute;
88
+ top: -10px;
89
+ right: 10px;
90
+ color: #D4A373;
91
+ font-size: 24px;
92
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));
93
+ }
94
+ .center-container {
95
+ display: flex;
96
+ flex-direction: column;
97
+ align-items: center;
98
+ justify-content: center;
99
+ }
100
+ .video-container {
101
+ position: relative;
102
+ width: 100%;
103
+ height: 0;
104
+ padding-bottom: 56.25%; /* 16:9 aspect ratio */
105
+ }
106
+ .video-player {
107
+ position: absolute;
108
+ top: 0;
109
+ left: 0;
110
+ width: 100%;
111
+ height: 100%;
112
+ background-color: #000;
113
+ }
114
+ .video-controls {
115
+ position: absolute;
116
+ bottom: 0;
117
+ left: 0;
118
+ right: 0;
119
+ background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
120
+ padding: 10px;
121
+ display: flex;
122
+ flex-direction: column;
123
+ opacity: 0;
124
+ transition: opacity 0.3s;
125
+ }
126
+ .video-container:hover .video-controls {
127
+ opacity: 1;
128
+ }
129
+ .fullscreen-btn {
130
+ position: absolute;
131
+ bottom: 10px;
132
+ right: 10px;
133
+ color: white;
134
+ background: rgba(0,0,0,0.5);
135
+ border-radius: 4px;
136
+ padding: 5px 8px;
137
+ cursor: pointer;
138
+ }
139
+ .story-content {
140
+ max-height: 400px;
141
+ overflow-y: auto;
142
+ padding-right: 10px;
143
+ }
144
+ .story-content::-webkit-scrollbar {
145
+ width: 6px;
146
+ }
147
+ .story-content::-webkit-scrollbar-track {
148
+ background: #f1f1f1;
149
+ border-radius: 10px;
150
+ }
151
+ .story-content::-webkit-scrollbar-thumb {
152
+ background: #D4A373;
153
+ border-radius: 10px;
154
+ }
155
+ .story-content p {
156
+ margin-bottom: 1rem;
157
+ line-height: 1.6;
158
+ }
159
+ </style>
160
+ </head>
161
+ <body class="bg-amber-50">
162
+ <div class="container mx-auto px-4 py-8 max-w-7xl center-container">
163
+ <!-- Header -->
164
+ <header class="flex flex-col md:flex-row justify-between items-center mb-12 w-full">
165
+ <div class="flex items-center mb-4 md:mb-0">
166
+ <div class="bg-amber-700 text-white p-3 rounded-lg mr-4">
167
+ <i class="fas fa-book-open text-2xl"></i>
168
+ </div>
169
+ <h1 class="text-4xl font-bold text-amber-900">Kho truyện Mã A Lềnh</h1>
170
+ </div>
171
+ <div class="flex space-x-2 bg-amber-100 p-2 rounded-full shadow-inner">
172
+ <button id="all-stories-btn" class="px-6 py-2 bg-amber-700 text-white rounded-full hover:bg-amber-800 transition-all duration-300 flex items-center">
173
+ <i class="fas fa-book mr-2"></i>
174
+ <span>Tất cả truyện</span>
175
+ </button>
176
+ <button id="favorites-btn" class="px-6 py-2 rounded-full hover:bg-amber-200 transition-all duration-300 flex items-center">
177
+ <i class="fas fa-heart mr-2 text-amber-700"></i>
178
+ <span>Yêu thích</span>
179
+ </button>
180
+ </div>
181
+ </header>
182
+
183
+ <!-- Main Content -->
184
+ <main class="w-full">
185
+ <!-- All Stories Section -->
186
+ <section id="all-stories" class="fade-in w-full">
187
+ <div class="flex flex-col md:flex-row justify-between items-center mb-8 w-full">
188
+ <div class="relative">
189
+ <select id="story-filter" class="appearance-none bg-amber-100 border border-amber-300 text-amber-900 py-2 px-4 pr-8 rounded-full focus:outline-none focus:ring-2 focus:ring-amber-500">
190
+ <option value="all">Tất cả thể loại</option>
191
+ <option value="children">Văn học thiếu nhi</option>
192
+ <option value="journal">Ký sự</option>
193
+ </select>
194
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-amber-700">
195
+ <i class="fas fa-chevron-down"></i>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 justify-items-center">
200
+ <!-- Story Card 1 -->
201
+ <div class="story-card bg-white rounded-xl shadow-lg overflow-hidden relative w-full max-w-sm">
202
+ <div class="relative">
203
+ <img src="https://i.imgur.com/nsjKQ2G.jpeg" alt="Chuyện con suối Mường Tiên" class="w-full h-64 object-cover">
204
+ <div class="story-tag tag-children">Văn học thiếu nhi</div>
205
+ <div class="play-overlay absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center opacity-0 transition-opacity">
206
+ <button class="play-btn" data-story="1">
207
+ <div class="bg-white bg-opacity-30 rounded-full p-4 hover:bg-opacity-50 transition">
208
+ <i class="fas fa-play text-white text-3xl"></i>
209
+ </div>
210
+ </button>
211
+ </div>
212
+ </div>
213
+ <div class="p-6">
214
+ <h3 class="text-xl font-bold mb-3 text-amber-900 text-center">Chuyện con suối Mường Tiên</h3>
215
+ <p class="text-amber-800 mb-4 text-sm text-center">Câu chuyện về Chà, cậu bé lớn lên bên suối Mường Tiên. Khi suối bị chặn lại để xây thủy điện, Chà quyết tâm học giỏi để cứu suối, phản ánh sự gắn bó giữa con người và thiên nhiên.</p>
216
+ <div class="flex justify-between items-center">
217
+ <div class="flex items-center text-sm text-amber-700">
218
+ <i class="fas fa-clock mr-2"></i>
219
+ <span>1:18 phút</span>
220
+ </div>
221
+ <button class="favorite-btn" data-story="1">
222
+ <i class="far fa-heart text-xl text-amber-600 hover:text-red-500 transition"></i>
223
+ </button>
224
+ </div>
225
+ </div>
226
+ </div>
227
+ <!-- Add other story cards -->
228
+ </div>
229
+ </section>
230
+ </main>
231
+ </div>
232
+
233
+ <script>
234
+ // JavaScript code for handling play/pause functionality and audio/video logic here
235
+ </script>
236
+ </body>
237
+ </html>
style.css ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ padding: 2rem;
3
+ font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
+ }
5
+
6
+ h1 {
7
+ font-size: 16px;
8
+ margin-top: 0;
9
+ }
10
+
11
+ p {
12
+ color: rgb(107, 114, 128);
13
+ font-size: 15px;
14
+ margin-bottom: 10px;
15
+ margin-top: 5px;
16
+ }
17
+
18
+ .card {
19
+ max-width: 620px;
20
+ margin: 0 auto;
21
+ padding: 16px;
22
+ border: 1px solid lightgray;
23
+ border-radius: 16px;
24
+ }
25
+
26
+ .card p:last-child {
27
+ margin-bottom: 0;
28
+ }
upload.html ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Upload Videos - Kho truyện Mã A Lềnh</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link
9
+ rel="stylesheet"
10
+ href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
11
+ />
12
+ <link
13
+ href="https://fonts.googleapis.com/css2?family=Noto+Serif:wght@400;700&display=swap"
14
+ rel="stylesheet"
15
+ />
16
+ <style>
17
+ body {
18
+ font-family: "Noto Serif", serif;
19
+ background-color: #fff9f0;
20
+ }
21
+ </style>
22
+ </head>
23
+ <body class="bg-amber-50">
24
+ <div class="container mx-auto px-4 py-8 max-w-2xl">
25
+ <div class="flex items-center mb-8">
26
+ <div class="bg-amber-700 text-white p-3 rounded-lg mr-4">
27
+ <i class="fas fa-upload text-2xl"></i>
28
+ </div>
29
+ <h1 class="text-3xl font-bold text-amber-900">Upload Videos</h1>
30
+ </div>
31
+
32
+ <div class="bg-white p-6 rounded-xl shadow-lg">
33
+ <h2 class="text-xl font-bold mb-4 text-amber-800">
34
+ Upload Story Videos
35
+ </h2>
36
+
37
+ <div class="space-y-6">
38
+ <!-- Video 1 -->
39
+ <div class="border border-amber-200 rounded-lg p-4">
40
+ <h3 class="font-bold text-amber-900 mb-2">
41
+ Chuyện con suối Mường Tiên
42
+ </h3>
43
+ <div class="mb-4">
44
+ <div class="relative">
45
+ <input
46
+ type="file"
47
+ id="video1"
48
+ name="video1"
49
+ accept="video/*"
50
+ class="hidden"
51
+ onchange="updateFileName(this, 'video1-name')"
52
+ />
53
+ <label
54
+ for="video1"
55
+ class="flex items-center justify-center px-4 py-2 bg-amber-100 text-amber-800 rounded-lg cursor-pointer hover:bg-amber-200 transition w-full"
56
+ >
57
+ <i class="fas fa-file-video mr-2"></i>
58
+ <span>Choose Video File</span>
59
+ </label>
60
+ <div id="video1-name" class="mt-2 text-sm text-gray-600">
61
+ No file chosen
62
+ </div>
63
+ </div>
64
+ </div>
65
+ <button
66
+ class="upload-btn w-full bg-amber-600 hover:bg-amber-700 text-white font-bold py-2 px-4 rounded-lg transition"
67
+ data-video="1"
68
+ data-filename="chuyen-con-suoi-muong-tien.mp4"
69
+ >
70
+ Upload Video
71
+ </button>
72
+ </div>
73
+
74
+ <!-- Video 2 -->
75
+ <div class="border border-amber-200 rounded-lg p-4">
76
+ <h3 class="font-bold text-amber-900 mb-2">
77
+ Chiếc bánh trong đẩy túi
78
+ </h3>
79
+ <div class="mb-4">
80
+ <div class="relative">
81
+ <input
82
+ type="file"
83
+ id="video2"
84
+ name="video2"
85
+ accept="video/*"
86
+ class="hidden"
87
+ onchange="updateFileName(this, 'video2-name')"
88
+ />
89
+ <label
90
+ for="video2"
91
+ class="flex items-center justify-center px-4 py-2 bg-amber-100 text-amber-800 rounded-lg cursor-pointer hover:bg-amber-200 transition w-full"
92
+ >
93
+ <i class="fas fa-file-video mr-2"></i>
94
+ <span>Choose Video File</span>
95
+ </label>
96
+ <div id="video2-name" class="mt-2 text-sm text-gray-600">
97
+ No file chosen
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <button
102
+ class="upload-btn w-full bg-amber-600 hover:bg-amber-700 text-white font-bold py-2 px-4 rounded-lg transition"
103
+ data-video="2"
104
+ data-filename="chiec-banh-trong-day-tui.mp4"
105
+ >
106
+ Upload Video
107
+ </button>
108
+ </div>
109
+
110
+ <!-- Video 3 -->
111
+ <div class="border border-amber-200 rounded-lg p-4">
112
+ <h3 class="font-bold text-amber-900 mb-2">
113
+ Vũng đầm của thần rồng
114
+ </h3>
115
+ <div class="mb-4">
116
+ <div class="relative">
117
+ <input
118
+ type="file"
119
+ id="video3"
120
+ name="video3"
121
+ accept="video/*"
122
+ class="hidden"
123
+ onchange="updateFileName(this, 'video3-name')"
124
+ />
125
+ <label
126
+ for="video3"
127
+ class="flex items-center justify-center px-4 py-2 bg-amber-100 text-amber-800 rounded-lg cursor-pointer hover:bg-amber-200 transition w-full"
128
+ >
129
+ <i class="fas fa-file-video mr-2"></i>
130
+ <span>Choose Video File</span>
131
+ </label>
132
+ <div id="video3-name" class="mt-2 text-sm text-gray-600">
133
+ No file chosen
134
+ </div>
135
+ </div>
136
+ </div>
137
+ <button
138
+ class="upload-btn w-full bg-amber-600 hover:bg-amber-700 text-white font-bold py-2 px-4 rounded-lg transition"
139
+ data-video="3"
140
+ data-filename="vung-dam-cua-than-rong.mp4"
141
+ >
142
+ Upload Video
143
+ </button>
144
+ </div>
145
+ </div>
146
+
147
+ <div class="mt-6 flex justify-between">
148
+ <a
149
+ href="index.html"
150
+ class="flex items-center text-amber-700 hover:text-amber-900 transition"
151
+ >
152
+ <i class="fas fa-arrow-left mr-2"></i>
153
+ <span>Back to Stories</span>
154
+ </a>
155
+ <div id="upload-status" class="text-green-600 font-bold"></div>
156
+ </div>
157
+ </div>
158
+ </div>
159
+
160
+ <script>
161
+ function updateFileName(input, targetId) {
162
+ const target = document.getElementById(targetId);
163
+ if (input.files.length > 0) {
164
+ target.textContent = input.files[0].name;
165
+ } else {
166
+ target.textContent = "No file chosen";
167
+ }
168
+ }
169
+
170
+ document.addEventListener("DOMContentLoaded", function () {
171
+ const uploadButtons = document.querySelectorAll(".upload-btn");
172
+
173
+ uploadButtons.forEach((button) => {
174
+ button.addEventListener("click", function () {
175
+ const videoId = this.getAttribute("data-video");
176
+ const targetFilename = this.getAttribute("data-filename");
177
+ const fileInput = document.getElementById("video" + videoId);
178
+ const statusElement = document.getElementById("upload-status");
179
+
180
+ if (!fileInput.files.length) {
181
+ statusElement.textContent = "Please select a file first.";
182
+ statusElement.className = "text-red-600 font-bold";
183
+ return;
184
+ }
185
+
186
+ const file = fileInput.files[0];
187
+
188
+ // In a real implementation, here you would upload the file to your server
189
+ // using fetch or FormData API. This is just a simulation:
190
+
191
+ button.textContent = "Uploading...";
192
+ button.disabled = true;
193
+
194
+ // Simulate upload delay
195
+ setTimeout(() => {
196
+ button.textContent = "Uploaded!";
197
+ button.classList.remove("bg-amber-600", "hover:bg-amber-700");
198
+ button.classList.add("bg-green-600", "hover:bg-green-700");
199
+
200
+ statusElement.textContent =
201
+ 'Video "' + targetFilename + '" has been selected.';
202
+ statusElement.className = "text-green-600 font-bold";
203
+
204
+ // After simulated upload, restore button
205
+ setTimeout(() => {
206
+ button.textContent = "Upload Video";
207
+ button.disabled = false;
208
+ button.classList.remove("bg-green-600", "hover:bg-green-700");
209
+ button.classList.add("bg-amber-600", "hover:bg-amber-700");
210
+ }, 3000);
211
+ }, 1500);
212
+ });
213
+ });
214
+ });
215
+ </script>
216
+ </body>
217
+ </html>
videos.js ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener("DOMContentLoaded", function () {
2
+ const videoModal = document.getElementById("video-modal");
3
+ const videoPlayer = document.getElementById("video-player");
4
+ const closeModalBtn = document.getElementById("close-modal");
5
+ const playButtons = document.querySelectorAll(".play-btn");
6
+ const favoriteButtons = document.querySelectorAll(".favorite-btn");
7
+
8
+ // Updated video sources using local video files
9
+ const videoSources = {
10
+ 1: "videos/chuyen-con-suoi-muong-tien.mp4",
11
+ 2: "videos/chiec-banh-trong-day-tui.mp4",
12
+ 3: "videos/vung-dam-cua-than-rong.mp4",
13
+ };
14
+
15
+ // Play button click handler
16
+ playButtons.forEach((button) => {
17
+ button.addEventListener("click", function () {
18
+ const storyId = this.getAttribute("data-story");
19
+ const videoSrc = videoSources[storyId];
20
+
21
+ // Set video source
22
+ videoPlayer.src = videoSrc;
23
+
24
+ // Show modal
25
+ videoModal.classList.remove("hidden");
26
+ videoModal.classList.add("flex");
27
+
28
+ // Play video
29
+ videoPlayer.load();
30
+ videoPlayer.play();
31
+ });
32
+ });
33
+
34
+ // Close modal button
35
+ closeModalBtn.addEventListener("click", function () {
36
+ // Pause video
37
+ videoPlayer.pause();
38
+
39
+ // Hide modal
40
+ videoModal.classList.add("hidden");
41
+ videoModal.classList.remove("flex");
42
+ });
43
+
44
+ // Pressing escape key also closes the modal
45
+ document.addEventListener("keydown", function (e) {
46
+ if (e.key === "Escape" && !videoModal.classList.contains("hidden")) {
47
+ videoPlayer.pause();
48
+ videoModal.classList.add("hidden");
49
+ videoModal.classList.remove("flex");
50
+ }
51
+ });
52
+
53
+ // Clicking outside the video container closes the modal
54
+ videoModal.addEventListener("click", function (e) {
55
+ if (e.target === videoModal) {
56
+ videoPlayer.pause();
57
+ videoModal.classList.add("hidden");
58
+ videoModal.classList.remove("flex");
59
+ }
60
+ });
61
+
62
+ // Favorite button click handler
63
+ favoriteButtons.forEach((button) => {
64
+ button.addEventListener("click", function () {
65
+ const heartIcon = this.querySelector("i");
66
+ const storyId = this.getAttribute("data-story");
67
+
68
+ if (heartIcon.classList.contains("far")) {
69
+ // Add to favorites
70
+ heartIcon.classList.remove("far");
71
+ heartIcon.classList.add("fas");
72
+ heartIcon.classList.add("text-red-500");
73
+
74
+ // Save to localStorage
75
+ saveFavorite(storyId);
76
+ } else {
77
+ // Remove from favorites
78
+ heartIcon.classList.remove("fas");
79
+ heartIcon.classList.remove("text-red-500");
80
+ heartIcon.classList.add("far");
81
+
82
+ // Remove from localStorage
83
+ removeFavorite(storyId);
84
+ }
85
+ });
86
+ });
87
+
88
+ // Load favorites from localStorage
89
+ function loadFavorites() {
90
+ const favorites = JSON.parse(localStorage.getItem("favorites")) || [];
91
+
92
+ favorites.forEach((id) => {
93
+ const button = document.querySelector(
94
+ `.favorite-btn[data-story="${id}"]`
95
+ );
96
+ if (button) {
97
+ const heartIcon = button.querySelector("i");
98
+ heartIcon.classList.remove("far");
99
+ heartIcon.classList.add("fas");
100
+ heartIcon.classList.add("text-red-500");
101
+ }
102
+ });
103
+ }
104
+
105
+ // Save a favorite to localStorage
106
+ function saveFavorite(id) {
107
+ const favorites = JSON.parse(localStorage.getItem("favorites")) || [];
108
+ if (!favorites.includes(id)) {
109
+ favorites.push(id);
110
+ localStorage.setItem("favorites", JSON.stringify(favorites));
111
+ }
112
+ }
113
+
114
+ // Remove a favorite from localStorage
115
+ function removeFavorite(id) {
116
+ let favorites = JSON.parse(localStorage.getItem("favorites")) || [];
117
+ favorites = favorites.filter((favoriteId) => favoriteId !== id);
118
+ localStorage.setItem("favorites", JSON.stringify(favorites));
119
+ }
120
+
121
+ // Initialize favorites
122
+ loadFavorites();
123
+
124
+ // Handle tab switching (All Stories / Favorites)
125
+ const allStoriesBtn = document.getElementById("all-stories-btn");
126
+ const favoritesBtn = document.getElementById("favorites-btn");
127
+ const allStoriesSection = document.getElementById("all-stories");
128
+
129
+ allStoriesBtn.addEventListener("click", function () {
130
+ // Show all stories
131
+ allStoriesBtn.classList.add("bg-amber-700", "text-white");
132
+ allStoriesBtn.classList.remove("hover:bg-amber-200");
133
+
134
+ favoritesBtn.classList.remove("bg-amber-700", "text-white");
135
+ favoritesBtn.classList.add("hover:bg-amber-200");
136
+
137
+ // Show all story cards
138
+ document.querySelectorAll(".story-card").forEach((card) => {
139
+ card.classList.remove("hidden");
140
+ });
141
+ });
142
+
143
+ favoritesBtn.addEventListener("click", function () {
144
+ // Show only favorites
145
+ favoritesBtn.classList.add("bg-amber-700", "text-white");
146
+ favoritesBtn.classList.remove("hover:bg-amber-200");
147
+
148
+ allStoriesBtn.classList.remove("bg-amber-700", "text-white");
149
+ allStoriesBtn.classList.add("hover:bg-amber-200");
150
+
151
+ const favorites = JSON.parse(localStorage.getItem("favorites")) || [];
152
+
153
+ // Hide/show cards based on favorites
154
+ document.querySelectorAll(".story-card").forEach((card) => {
155
+ const storyId = card
156
+ .querySelector(".play-btn")
157
+ .getAttribute("data-story");
158
+ if (favorites.includes(storyId)) {
159
+ card.classList.remove("hidden");
160
+ } else {
161
+ card.classList.add("hidden");
162
+ }
163
+ });
164
+ });
165
+ });