TRM117 commited on
Commit
d397019
·
verified ·
1 Parent(s): 91f3de1

I need to be able to add custom races as well and my files I have that I need to upload are .doc files

Browse files
Files changed (3) hide show
  1. index.html +25 -1
  2. script.js +174 -6
  3. style.css +11 -5
index.html CHANGED
@@ -85,8 +85,32 @@
85
  </div>
86
  </div>
87
  </section>
88
- <!-- Character Classes -->
89
  <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  <h2 class="text-2xl font-bold text-primary-500 mb-4">
91
  <i data-feather="users" class="inline mr-2"></i>
92
  Design Character Classes
 
85
  </div>
86
  </div>
87
  </section>
88
+ <!-- Races -->
89
  <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
90
+ <h2 class="text-2xl font-bold text-primary-500 mb-4">
91
+ <i data-feather="users" class="inline mr-2"></i>
92
+ Define Races
93
+ </h2>
94
+ <div class="flex items-center space-x-4 mb-4">
95
+ <label class="relative cursor-pointer bg-gray-100 hover:bg-gray-200 px-4 py-2 rounded-lg transition">
96
+ <span class="flex items-center">
97
+ <i data-feather="upload" class="mr-2 w-4 h-4"></i>
98
+ Upload Races File
99
+ </span>
100
+ <input type="file" id="races-upload" accept=".doc,.docx,.json,.txt" class="hidden">
101
+ </label>
102
+ <span class="text-sm text-gray-500">or create manually below</span>
103
+ </div>
104
+ <div id="races-container">
105
+ <!-- Races will be added here -->
106
+ </div>
107
+ <button id="add-race-btn" class="mt-4 flex items-center text-secondary-500 font-medium hover:text-secondary-600">
108
+ <i data-feather="plus" class="mr-2"></i> Add New Race
109
+ </button>
110
+ </section>
111
+
112
+ <!-- Character Classes -->
113
+ <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
114
  <h2 class="text-2xl font-bold text-primary-500 mb-4">
115
  <i data-feather="users" class="inline mr-2"></i>
116
  Design Character Classes
script.js CHANGED
@@ -1,9 +1,9 @@
1
 
2
  document.addEventListener('DOMContentLoaded', function() {
3
- // Initialize class counter
4
  let classCount = 0;
5
-
6
- // Handle lore file upload
7
  document.getElementById('lore-upload').addEventListener('change', function(e) {
8
  const file = e.target.files[0];
9
  if (!file) return;
@@ -28,9 +28,105 @@ document.addEventListener('DOMContentLoaded', function() {
28
  };
29
  reader.readAsText(file);
30
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  // Handle classes file upload
33
- document.getElementById('classes-upload').addEventListener('change', function(e) {
34
  const file = e.target.files[0];
35
  if (!file) return;
36
 
@@ -150,8 +246,80 @@ document.addEventListener('DOMContentLoaded', function() {
150
  container.removeChild(abilityDiv);
151
  });
152
  }
153
- // Add class button functionality
154
- document.getElementById('add-class-btn').addEventListener('click', function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  classCount++;
156
  const container = document.getElementById('classes-container');
157
 
 
1
 
2
  document.addEventListener('DOMContentLoaded', function() {
3
+ // Initialize counters
4
  let classCount = 0;
5
+ let raceCount = 0;
6
+ // Handle lore file upload
7
  document.getElementById('lore-upload').addEventListener('change', function(e) {
8
  const file = e.target.files[0];
9
  if (!file) return;
 
28
  };
29
  reader.readAsText(file);
30
  });
31
+ // Handle races file upload
32
+ document.getElementById('races-upload').addEventListener('change', function(e) {
33
+ const file = e.target.files[0];
34
+ if (!file) return;
35
+
36
+ const reader = new FileReader();
37
+ reader.onload = function(e) {
38
+ try {
39
+ let racesData;
40
+ if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) {
41
+ // For DOC files, we'll just display the raw text
42
+ racesData = [{name: 'Imported DOC', description: e.target.result}];
43
+ } else {
44
+ racesData = JSON.parse(e.target.result);
45
+ }
46
+
47
+ const container = document.getElementById('races-container');
48
+ container.innerHTML = ''; // Clear existing races
49
+
50
+ racesData.forEach((raceData, index) => {
51
+ raceCount++;
52
+ const raceCard = document.createElement('div');
53
+ raceCard.className = 'race-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4';
54
+ raceCard.innerHTML = `
55
+ <div class="flex justify-between items-start mb-2">
56
+ <h3 class="font-semibold text-lg">${raceData.name || `New Race #${index+1}`}</h3>
57
+ <button class="text-red-500 hover:text-red-600">
58
+ <i data-feather="trash-2"></i>
59
+ </button>
60
+ </div>
61
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
62
+ <div class="md:col-span-2">
63
+ <label class="block text-gray-700 mb-1 text-sm">Race Description</label>
64
+ <textarea rows="3" class="w-full px-3 py-1 border border-gray-300 rounded-md">${raceData.description || ''}</textarea>
65
+ </div>
66
+ <div>
67
+ <label class="block text-gray-700 mb-1 text-sm">Size</label>
68
+ <select class="w-full px-3 py-1 border border-gray-300 rounded-md">
69
+ <option ${raceData.size === 'Small' ? 'selected' : ''}>Small</option>
70
+ <option ${raceData.size === 'Medium' ? 'selected' : ''}>Medium</option>
71
+ <option ${raceData.size === 'Large' ? 'selected' : ''}>Large</option>
72
+ </select>
73
+ </div>
74
+ <div>
75
+ <label class="block text-gray-700 mb-1 text-sm">Speed</label>
76
+ <input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="${raceData.speed || '30'}">
77
+ </div>
78
+ <div class="md:col-span-2">
79
+ <label class="block text-gray-700 mb-1 text-sm">Racial Traits</label>
80
+ <div class="traits-container space-y-2">
81
+ ${raceData.traits ? raceData.traits.map(trait => `
82
+ <div class="flex items-center">
83
+ <input type="text" class="flex-1 px-2 py-1 border border-gray-300 rounded-md mr-2" value="${trait}">
84
+ <button class="text-red-500 hover:text-red-600">
85
+ <i data-feather="x" class="w-4 h-4"></i>
86
+ </button>
87
+ </div>
88
+ `).join('') : ''}
89
+ </div>
90
+ <button class="mt-2 text-sm text-secondary-500 hover:text-secondary-600 flex items-center">
91
+ <i data-feather="plus" class="w-4 h-4 mr-1"></i> Add Trait
92
+ </button>
93
+ </div>
94
+ </div>
95
+ `;
96
+
97
+ container.appendChild(raceCard);
98
+ feather.replace();
99
+
100
+ // Add event listener for delete button
101
+ raceCard.querySelector('button').addEventListener('click', function() {
102
+ container.removeChild(raceCard);
103
+ raceCount--;
104
+ });
105
+
106
+ // Add event listener for add trait button
107
+ const traitsBtn = raceCard.querySelector('.traits-container').nextElementSibling;
108
+ traitsBtn.addEventListener('click', function() {
109
+ addTraitField(this.previousElementSibling);
110
+ });
111
+ });
112
+ } catch (error) {
113
+ alert('Error processing races file. Showing raw content.');
114
+ const container = document.getElementById('races-container');
115
+ container.innerHTML = `<div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
116
+ <h3 class="font-semibold text-lg mb-2">File Content</h3>
117
+ <pre class="whitespace-pre-wrap">${e.target.result}</pre>
118
+ </div>`;
119
+ }
120
+ };
121
+ if (file.name.endsWith('.doc') || file.name.endsWith('.docx')) {
122
+ reader.readAsText(file);
123
+ } else {
124
+ reader.readAsText(file);
125
+ }
126
+ });
127
 
128
  // Handle classes file upload
129
+ document.getElementById('classes-upload').addEventListener('change', function(e) {
130
  const file = e.target.files[0];
131
  if (!file) return;
132
 
 
246
  container.removeChild(abilityDiv);
247
  });
248
  }
249
+ // Add race button functionality
250
+ document.getElementById('add-race-btn').addEventListener('click', function() {
251
+ raceCount++;
252
+ const container = document.getElementById('races-container');
253
+
254
+ const raceCard = document.createElement('div');
255
+ raceCard.className = 'race-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4';
256
+ raceCard.innerHTML = `
257
+ <div class="flex justify-between items-start mb-2">
258
+ <h3 class="font-semibold text-lg">New Race #${raceCount}</h3>
259
+ <button class="text-red-500 hover:text-red-600">
260
+ <i data-feather="trash-2"></i>
261
+ </button>
262
+ </div>
263
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
264
+ <div class="md:col-span-2">
265
+ <label class="block text-gray-700 mb-1 text-sm">Race Description</label>
266
+ <textarea rows="3" class="w-full px-3 py-1 border border-gray-300 rounded-md"></textarea>
267
+ </div>
268
+ <div>
269
+ <label class="block text-gray-700 mb-1 text-sm">Size</label>
270
+ <select class="w-full px-3 py-1 border border-gray-300 rounded-md">
271
+ <option>Small</option>
272
+ <option selected>Medium</option>
273
+ <option>Large</option>
274
+ </select>
275
+ </div>
276
+ <div>
277
+ <label class="block text-gray-700 mb-1 text-sm">Speed</label>
278
+ <input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="30">
279
+ </div>
280
+ <div class="md:col-span-2">
281
+ <label class="block text-gray-700 mb-1 text-sm">Racial Traits</label>
282
+ <div class="traits-container space-y-2"></div>
283
+ <button class="mt-2 text-sm text-secondary-500 hover:text-secondary-600 flex items-center">
284
+ <i data-feather="plus" class="w-4 h-4 mr-1"></i> Add Trait
285
+ </button>
286
+ </div>
287
+ </div>
288
+ `;
289
+
290
+ container.appendChild(raceCard);
291
+ feather.replace();
292
+
293
+ // Add event listener for delete button
294
+ raceCard.querySelector('button').addEventListener('click', function() {
295
+ container.removeChild(raceCard);
296
+ raceCount--;
297
+ });
298
+
299
+ // Add event listener for add trait button
300
+ const traitsBtn = raceCard.querySelector('.traits-container').nextElementSibling;
301
+ traitsBtn.addEventListener('click', function() {
302
+ const traitsContainer = this.previousElementSibling;
303
+ const traitDiv = document.createElement('div');
304
+ traitDiv.className = 'flex items-center';
305
+ traitDiv.innerHTML = `
306
+ <input type="text" class="flex-1 px-2 py-1 border border-gray-300 rounded-md mr-2" placeholder="Trait name">
307
+ <button class="text-red-500 hover:text-red-600">
308
+ <i data-feather="x" class="w-4 h-4"></i>
309
+ </button>
310
+ `;
311
+ traitsContainer.appendChild(traitDiv);
312
+ feather.replace();
313
+
314
+ // Add event listener for delete trait button
315
+ traitDiv.querySelector('button').addEventListener('click', function() {
316
+ traitsContainer.removeChild(traitDiv);
317
+ });
318
+ });
319
+ });
320
+
321
+ // Add class button functionality
322
+ document.getElementById('add-class-btn').addEventListener('click', function() {
323
  classCount++;
324
  const container = document.getElementById('classes-container');
325
 
style.css CHANGED
@@ -38,12 +38,18 @@ input[type="file"] + span {
38
  input[type="file"]:hover + span {
39
  background-color: #e5e7eb;
40
  }
41
-
42
- /* Character class card styles */
43
- .class-card {
44
  transition: all 0.3s ease;
45
  }
46
- .class-card:hover {
47
  transform: translateY(-5px);
48
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
49
- }
 
 
 
 
 
 
 
 
38
  input[type="file"]:hover + span {
39
  background-color: #e5e7eb;
40
  }
41
+ /* Race and class card styles */
42
+ .race-card, .class-card {
 
43
  transition: all 0.3s ease;
44
  }
45
+ .race-card:hover, .class-card:hover {
46
  transform: translateY(-5px);
47
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
48
+ }
49
+
50
+ /* DOC file upload styling */
51
+ input[type="file"][accept*=".doc"] + span::after {
52
+ content: " (DOC/DOCX)";
53
+ font-size: 0.8em;
54
+ color: #6b7280;
55
+ }