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

I have my own files for classes and lore I want to be able to upload

Browse files
Files changed (3) hide show
  1. index.html +22 -4
  2. script.js +150 -2
  3. style.css +8 -1
index.html CHANGED
@@ -54,7 +54,6 @@
54
  </div>
55
  </div>
56
  </section>
57
-
58
  <!-- Lore Creation -->
59
  <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
60
  <h2 class="text-2xl font-bold text-primary-500 mb-4">
@@ -62,7 +61,17 @@
62
  Craft Your Lore
63
  </h2>
64
  <div class="space-y-4">
65
- <div>
 
 
 
 
 
 
 
 
 
 
66
  <label class="block text-gray-700 mb-2">World Name</label>
67
  <input type="text" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500">
68
  </div>
@@ -76,15 +85,24 @@
76
  </div>
77
  </div>
78
  </section>
79
-
80
  <!-- Character Classes -->
81
  <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
82
  <h2 class="text-2xl font-bold text-primary-500 mb-4">
83
  <i data-feather="users" class="inline mr-2"></i>
84
  Design Character Classes
85
  </h2>
 
 
 
 
 
 
 
 
 
 
86
  <div id="classes-container">
87
- <!-- Classes will be added here -->
88
  </div>
89
  <button id="add-class-btn" class="mt-4 flex items-center text-secondary-500 font-medium hover:text-secondary-600">
90
  <i data-feather="plus" class="mr-2"></i> Add New Class
 
54
  </div>
55
  </div>
56
  </section>
 
57
  <!-- Lore Creation -->
58
  <section class="mb-12 bg-white rounded-xl shadow-lg p-6">
59
  <h2 class="text-2xl font-bold text-primary-500 mb-4">
 
61
  Craft Your Lore
62
  </h2>
63
  <div class="space-y-4">
64
+ <div class="flex items-center space-x-4 mb-4">
65
+ <label class="relative cursor-pointer bg-gray-100 hover:bg-gray-200 px-4 py-2 rounded-lg transition">
66
+ <span class="flex items-center">
67
+ <i data-feather="upload" class="mr-2 w-4 h-4"></i>
68
+ Upload Lore File
69
+ </span>
70
+ <input type="file" id="lore-upload" accept=".json,.txt,.md" class="hidden">
71
+ </label>
72
+ <span class="text-sm text-gray-500">or create manually below</span>
73
+ </div>
74
+ <div>
75
  <label class="block text-gray-700 mb-2">World Name</label>
76
  <input type="text" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500">
77
  </div>
 
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
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 Classes File
99
+ </span>
100
+ <input type="file" id="classes-upload" accept=".json,.txt,.md" class="hidden">
101
+ </label>
102
+ <span class="text-sm text-gray-500">or create manually below</span>
103
+ </div>
104
  <div id="classes-container">
105
+ <!-- Classes will be added here -->
106
  </div>
107
  <button id="add-class-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 Class
script.js CHANGED
@@ -1,8 +1,156 @@
 
1
  document.addEventListener('DOMContentLoaded', function() {
2
  // Initialize class counter
3
  let classCount = 0;
4
-
5
- // Add class button functionality
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  document.getElementById('add-class-btn').addEventListener('click', function() {
7
  classCount++;
8
  const container = document.getElementById('classes-container');
 
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;
10
+
11
+ const reader = new FileReader();
12
+ reader.onload = function(e) {
13
+ try {
14
+ const loreData = JSON.parse(e.target.result);
15
+ // Populate lore fields with uploaded data
16
+ if (loreData.worldName) {
17
+ document.querySelector('input[type="text"]').value = loreData.worldName;
18
+ }
19
+ if (loreData.backgroundStory) {
20
+ document.querySelector('textarea').value = loreData.backgroundStory;
21
+ }
22
+ if (loreData.majorFactions) {
23
+ document.querySelectorAll('input[type="text"]')[1].value = loreData.majorFactions;
24
+ }
25
+ } catch (error) {
26
+ alert('Error parsing lore file. Please check the format.');
27
+ }
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
+
37
+ const reader = new FileReader();
38
+ reader.onload = function(e) {
39
+ try {
40
+ const classesData = JSON.parse(e.target.result);
41
+ const container = document.getElementById('classes-container');
42
+ container.innerHTML = ''; // Clear existing classes
43
+
44
+ classesData.forEach((classData, index) => {
45
+ classCount++;
46
+ const classCard = document.createElement('div');
47
+ classCard.className = 'class-card bg-gray-50 p-4 rounded-lg border border-gray-200 mb-4';
48
+ classCard.innerHTML = `
49
+ <div class="flex justify-between items-start mb-2">
50
+ <h3 class="font-semibold text-lg">${classData.name || `New Class #${index+1}`}</h3>
51
+ <button class="text-red-500 hover:text-red-600">
52
+ <i data-feather="trash-2"></i>
53
+ </button>
54
+ </div>
55
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
56
+ <div>
57
+ <label class="block text-gray-700 mb-1 text-sm">Class Name</label>
58
+ <input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="${classData.name || ''}">
59
+ </div>
60
+ <div>
61
+ <label class="block text-gray-700 mb-1 text-sm">Primary Attribute</label>
62
+ <select class="w-full px-3 py-1 border border-gray-300 rounded-md">
63
+ <option ${classData.attribute === 'Strength' ? 'selected' : ''}>Strength</option>
64
+ <option ${classData.attribute === 'Dexterity' ? 'selected' : ''}>Dexterity</option>
65
+ <option ${classData.attribute === 'Intelligence' ? 'selected' : ''}>Intelligence</option>
66
+ <option ${classData.attribute === 'Wisdom' ? 'selected' : ''}>Wisdom</option>
67
+ <option ${classData.attribute === 'Charisma' ? 'selected' : ''}>Charisma</option>
68
+ <option ${classData.attribute === 'Constitution' ? 'selected' : ''}>Constitution</option>
69
+ </select>
70
+ </div>
71
+ <div>
72
+ <label class="block text-gray-700 mb-1 text-sm">Hit Points</label>
73
+ <input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="${classData.hitPoints || '1d8'}">
74
+ </div>
75
+ <div>
76
+ <label class="block text-gray-700 mb-1 text-sm">Armor Proficiency</label>
77
+ <select class="w-full px-3 py-1 border border-gray-300 rounded-md">
78
+ <option ${classData.armor === 'Light' ? 'selected' : ''}>Light</option>
79
+ <option ${classData.armor === 'Medium' ? 'selected' : ''}>Medium</option>
80
+ <option ${classData.armor === 'Heavy' ? 'selected' : ''}>Heavy</option>
81
+ <option ${classData.armor === 'None' ? 'selected' : ''}>None</option>
82
+ </select>
83
+ </div>
84
+ <div class="md:col-span-2">
85
+ <label class="block text-gray-700 mb-1 text-sm">Class Description</label>
86
+ <textarea rows="2" class="w-full px-3 py-1 border border-gray-300 rounded-md">${classData.description || ''}</textarea>
87
+ </div>
88
+ <div class="md:col-span-2">
89
+ <label class="block text-gray-700 mb-1 text-sm">Special Abilities</label>
90
+ <div class="abilities-container space-y-2">
91
+ ${classData.abilities ? classData.abilities.map(ability => `
92
+ <div class="flex items-center">
93
+ <input type="text" class="flex-1 px-2 py-1 border border-gray-300 rounded-md mr-2" value="${ability}">
94
+ <button class="text-red-500 hover:text-red-600">
95
+ <i data-feather="x" class="w-4 h-4"></i>
96
+ </button>
97
+ </div>
98
+ `).join('') : ''}
99
+ </div>
100
+ <button class="mt-2 text-sm text-secondary-500 hover:text-secondary-600 flex items-center">
101
+ <i data-feather="plus" class="w-4 h-4 mr-1"></i> Add Ability
102
+ </button>
103
+ </div>
104
+ </div>
105
+ `;
106
+
107
+ container.appendChild(classCard);
108
+ feather.replace();
109
+
110
+ // Add event listener for delete button
111
+ classCard.querySelector('button').addEventListener('click', function() {
112
+ container.removeChild(classCard);
113
+ classCount--;
114
+ });
115
+
116
+ // Add event listeners for abilities
117
+ const abilitiesBtn = classCard.querySelector('.abilities-container').nextElementSibling;
118
+ abilitiesBtn.addEventListener('click', function() {
119
+ addAbilityField(this.previousElementSibling);
120
+ });
121
+
122
+ // Add event listeners for existing ability delete buttons
123
+ classCard.querySelectorAll('.abilities-container button').forEach(btn => {
124
+ btn.addEventListener('click', function() {
125
+ this.parentElement.remove();
126
+ });
127
+ });
128
+ });
129
+ } catch (error) {
130
+ alert('Error parsing classes file. Please check the format.');
131
+ }
132
+ };
133
+ reader.readAsText(file);
134
+ });
135
+
136
+ function addAbilityField(container) {
137
+ const abilityDiv = document.createElement('div');
138
+ abilityDiv.className = 'flex items-center';
139
+ abilityDiv.innerHTML = `
140
+ <input type="text" class="flex-1 px-2 py-1 border border-gray-300 rounded-md mr-2" placeholder="Ability name">
141
+ <button class="text-red-500 hover:text-red-600">
142
+ <i data-feather="x" class="w-4 h-4"></i>
143
+ </button>
144
+ `;
145
+ container.appendChild(abilityDiv);
146
+ feather.replace();
147
+
148
+ // Add event listener for delete ability button
149
+ abilityDiv.querySelector('button').addEventListener('click', 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');
style.css CHANGED
@@ -30,12 +30,19 @@ button:hover {
30
  ::-webkit-scrollbar-thumb:hover {
31
  background: #555;
32
  }
 
 
 
 
 
 
 
 
33
 
34
  /* Character class card styles */
35
  .class-card {
36
  transition: all 0.3s ease;
37
  }
38
-
39
  .class-card:hover {
40
  transform: translateY(-5px);
41
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
 
30
  ::-webkit-scrollbar-thumb:hover {
31
  background: #555;
32
  }
33
+ /* Upload button styles */
34
+ input[type="file"] + span {
35
+ transition: all 0.2s ease;
36
+ }
37
+
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);