Fixed Errors

This commit is contained in:
2025-08-01 01:32:46 +01:00
parent 6075472f3d
commit ae015a53c3
2 changed files with 89 additions and 41 deletions
+63 -1
View File
@@ -61,7 +61,17 @@
</div>
<div class="generators-grid" :class="`grid-${generators.length}`">
<NameGeneratorCard v-for="id in generators" :key="id" :card-id="id" />
<NameGeneratorCard
v-for="id in generators"
:key="id"
:card-id="id"
@show-toast="handleToast"
/>
</div>
<!-- Page-level toast notification -->
<div v-if="showToast" class="page-toast" :class="`toast-${toastType}`">
{{ toastMessage }}
</div>
</div>
</template>
@@ -73,6 +83,20 @@ import NameGeneratorCard from "./NameGeneratorCard.vue";
const generators = ref([1, 2, 3, 4]);
let nextId = 5;
// Toast state
const showToast = ref(false);
const toastMessage = ref("");
const toastType = ref("success");
function handleToast(event) {
toastMessage.value = event.message;
toastType.value = event.type;
showToast.value = true;
setTimeout(() => {
showToast.value = false;
}, event.type === "error" ? 4000 : 2000);
}
function addGenerator() {
if (generators.value.length < 6) {
generators.value.push(nextId++);
@@ -215,4 +239,42 @@ function removeGenerator() {
justify-content: center;
}
}
/* Page-level toast */
.page-toast {
position: fixed;
top: var(--spacing-lg);
right: var(--spacing-lg);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
font-size: 0.9rem;
font-weight: 600;
z-index: 1000;
animation: slideInRight 0.3s ease;
max-width: 400px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.toast-success {
background: #10b981;
color: white;
border: 1px solid #059669;
}
.toast-error {
background: #ef4444;
color: white;
border: 1px solid #dc2626;
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
</style>
+26 -40
View File
@@ -129,11 +129,6 @@
</svg>
</li>
</ul>
<!-- Toast notification -->
<div v-if="showToast" class="toast">
{{ toastMessage }}
</div>
</div>
</template>
@@ -147,6 +142,8 @@ const props = defineProps({
},
});
const emit = defineEmits(['show-toast']);
const modern = ref(false);
const isLoading = ref(false);
@@ -208,8 +205,6 @@ const race = ref(races[0].value);
const language = ref("english");
const gender = ref("male");
const fullNames = ref([]);
const showToast = ref(false);
const toastMessage = ref("");
function resetGenerator() {
modern.value = false;
@@ -217,7 +212,6 @@ function resetGenerator() {
language.value = "english";
gender.value = "male";
fullNames.value = [];
showToast.value = false;
}
async function generate() {
@@ -227,7 +221,7 @@ async function generate() {
try {
if (modern.value) {
// Use API for modern names
const url = `https://namegen.fernandovideira.com/v1/modern/${language.value}?gender=${gender.value}`;
const url = `http://localhost:8080/v1/modern/${language.value}?gender=${gender.value}`;
const response = await fetch(url);
if (!response.ok) {
@@ -236,18 +230,21 @@ async function generate() {
const data = await response.json();
if (data.success && data.names) {
if (data.names) {
fullNames.value = data.names;
} else {
console.error(
"Failed to fetch modern names:",
data.message || "Unknown error"
);
fullNames.value = ["Error generating names"];
emit('show-toast', {
message: `Error: ${data.message || "Failed to generate modern names"}`,
type: 'error'
});
}
} else {
// Use API for fantasy names
const url = `https://namegen.fernandovideira.com/v1/fantasy/${race.value}-names?gender=${gender.value}`;
const url = `http://localhost:8080/v1/fantasy/${race.value}-names?gender=${gender.value}`;
const response = await fetch(url);
if (!response.ok) {
@@ -256,19 +253,25 @@ async function generate() {
const data = await response.json();
if (data.success && data.names) {
if (data.names) {
fullNames.value = data.names;
} else {
console.error(
"Failed to fetch fantasy names:",
data.message || "Unknown error"
);
fullNames.value = ["Error generating names"];
emit('show-toast', {
message: `Error: ${data.message || "Failed to generate fantasy names"}`,
type: 'error'
});
}
}
} catch (error) {
console.error("Error fetching names:", error);
fullNames.value = [`Error: ${error.message}`];
emit('show-toast', {
message: `Connection error: ${error.message}`,
type: 'error'
});
} finally {
isLoading.value = false;
}
@@ -277,7 +280,10 @@ async function generate() {
async function copyToClipboard(name) {
try {
await navigator.clipboard.writeText(name);
showToastMessage(`"${name}" copied to clipboard!`);
emit('show-toast', {
message: `"${name}" copied to clipboard!`,
type: 'success'
});
} catch (err) {
console.error("Failed to copy to clipboard:", err);
// Fallback for older browsers
@@ -287,17 +293,12 @@ async function copyToClipboard(name) {
textArea.select();
document.execCommand("copy");
document.body.removeChild(textArea);
showToastMessage(`"${name}" copied to clipboard!`);
emit('show-toast', {
message: `"${name}" copied to clipboard!`,
type: 'success'
});
}
}
function showToastMessage(message) {
toastMessage.value = message;
showToast.value = true;
setTimeout(() => {
showToast.value = false;
}, 2000);
}
</script>
<style scoped>
@@ -490,21 +491,6 @@ select:focus {
opacity: 1;
}
.toast {
position: absolute;
bottom: var(--spacing-sm);
left: 50%;
transform: translateX(-50%);
background: var(--success);
color: var(--success-text);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--border-radius);
font-size: 0.8rem;
font-weight: 500;
z-index: 10;
animation: slideUp 0.3s ease;
}
@keyframes slideUp {
from {
opacity: 0;