Rewind from a user account system. Not necessary.

This commit is contained in:
DesertMermaid 2024-11-16 15:26:35 -08:00
parent 640f81a79f
commit 0ea172d6ad
22 changed files with 8 additions and 3032 deletions

View file

@ -2,10 +2,6 @@
import { RouterLink, RouterView } from 'vue-router';
import { ref, onMounted } from 'vue';
// Authentication state
const isAuthenticated = ref(false);
const username = ref("");
// Theme state and available themes
const theme = ref(localStorage.getItem("theme") || "mocha");
const availableThemes = [
@ -23,24 +19,11 @@ const availableThemes = [
"daydreamer",
];
// Apply theme and check authentication state
// Apply theme
onMounted(() => {
const token = localStorage.getItem("token");
if (token) {
isAuthenticated.value = true;
username.value = localStorage.getItem("username") || "";
}
document.documentElement.setAttribute("data-theme", theme.value);
});
// Logout function
const logout = () => {
localStorage.removeItem("token");
localStorage.removeItem("username");
isAuthenticated.value = false;
window.location.href = "/";
};
// Change theme function
const changeTheme = (newTheme: string) => {
theme.value = newTheme;
@ -57,37 +40,21 @@ const changeTheme = (newTheme: string) => {
<div class="nav-links">
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/servers">Servers</RouterLink>
<RouterLink to="/projects">Projects</RouterLink>
<RouterLink v-if="isAuthenticated" to="/recipes">Recipes</RouterLink>
<RouterLink v-if="isAuthenticated" to="/calendar">Calendar</RouterLink>
<RouterLink v-if="isAuthenticated" to="/gallery">Gallery</RouterLink>
<RouterLink to="/projects">Projects</RouterLink>"
<a href="https://foundryvtt.example.com" target="_blank">Foundry VTT</a>
<a href="https://oekaki.smgames.club" target="_blank">Oekaki</a>
<a href="https://social.smgames.club/" target="_blank">Social</a>
<a href="https://madstar.studio" target="_blank">Shop</a>
</div>
</nav>
</header>
<!-- Authentication & Theme Controls -->
<section class="controls">
<div class="theme-selector">
<!-- Theme Selector -->
<div class="theme-selector">
<label for="theme-switcher">Theme:</label>
<select id="theme-switcher" v-model="theme" @change="changeTheme(theme)">
<option v-for="t in availableThemes" :key="t" :value="t">{{ t }}</option>
</select>
</div>
<div class="auth-controls">
<span v-if="isAuthenticated">
Welcome, {{ username }}!
<button @click="logout" class="logout-button">Logout</button>
</span>
<span v-else>
<RouterLink to="/login">Login</RouterLink>&nbsp;&nbsp;|&nbsp;
<RouterLink to="/register">Register</RouterLink>
</span>
</div>
</section>
</nav>
</header>
<!-- Main Content -->
<main>

View file

@ -19,31 +19,6 @@ const router = createRouter({
name: 'projects',
component: () => import('../views/ProjectsView.vue'),
},
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue'),
},
{
path: '/register',
name: 'register',
component: () => import('../views/RegisterView.vue'),
},
{
path: '/gallery',
name: 'gallery',
component: () => import('../views/GalleryView.vue'),
},
{
path: '/calendar',
name: 'calendar',
component: () => import('../views/CalendarView.vue'),
},
{
path: '/recipes',
name: 'recipes',
component: () => import('../views/RecipesView.vue'),
},
// Example for adding a new page
/*
{

View file

@ -1,13 +1,5 @@
<template>
<div class="landing-page">
<header class="hero">
<div class="hero-content">
<h1>Welcome to the Server Tower</h1>
<p>
Explore our hosted tools, services, and projects for personal use, family, and creative endeavors.
</p>
</div>
</header>
<section class="sections">
<!-- Family Content -->
@ -19,37 +11,11 @@
<h3>Sharkey</h3>
<p>
Twitter alternative without a flood of Nazis.<br /><br />
We manually approve all members + verify them outside of the net, too.<br /><br />
Fam & friends only to make an account in our space, but you can use any Sharkey/Mastodon/etc instance to register elsewhere and talk to us.
We manually approve all members + verify them outside of the net, too. Fam & friends only to make an account in our space, but you can use any Sharkey/Mastodon/etc instance to register elsewhere and talk to us.
</p>
<a href="https://social.smgames.club/" class="link">Go to Platform</a>
</div>
<!-- Conditional Sections (Visible only if logged in) -->
<div v-if="isAuthenticated" class="card">
<h3>Discord</h3>
<p>
Connect with others on our private Discord... which is by invite only!<br /><br />
Sorry, you won't actually find the link here! If you're related to Starr, ask her about it.
</p>
</div>
<div v-if="isAuthenticated" class="card">
<h3>Photo Gallery</h3>
<p>Explore our collection of family photos, preserved for generations.</p>
<a href="/gallery" class="link">View Photos</a>
</div>
<div v-if="isAuthenticated" class="card">
<h3>Recipe Collection</h3>
<p>Browse our curated family recipes, shared across generations.</p>
<a href="/recipes" class="link">Explore Recipes</a>
</div>
</div>
</div>
<!-- Gaming Content -->
<div class="section-box">
<h2>Gaming</h2>
<div class="section-content">
<div class="card">
<h3>Game Servers</h3>
<p>
@ -82,10 +48,3 @@
</section>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// Authentication state from App.vue
const isAuthenticated = ref(false); // Replace this with a global state or a store (e.g., Pinia/Vuex) if necessary
</script>

View file

@ -1,44 +0,0 @@
<template>
<div class="login">
<h1>Login</h1>
<form @submit.prevent="handleLogin">
<div class="form-group">
<input v-model="username" type="text" placeholder="Username" required />
</div>
<div class="form-group">
<input v-model="password" type="password" placeholder="Password" required />
</div>
<button type="submit" class="btn-login">Login</button>
</form>
<p v-if="error" class="error">{{ error }}</p>
<p class="register-link">
Don't have an account? <router-link to="/register">Register here</router-link>.
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { login } from "@/authService"; // Matches the renamed file
export default defineComponent({
data() {
return {
username: "",
password: "",
error: "",
};
},
methods: {
async handleLogin() {
try {
await login(this.username, this.password);
this.$router.push("/protected"); // Redirect to protected route
} catch (error) {
console.error(error);
this.error = "Invalid username or password";
}
},
},
});
</script>

View file

@ -1,253 +0,0 @@
<template>
<div class="recipes">
<h1>Recipes</h1>
<div class="filter-bar">
<div class="filter-group">
<label for="type">Filter by Type:</label>
<select v-model="selectedType" @change="filterRecipes">
<option value="">All</option>
<option value="appetizer">Appetizers</option>
<option value="drink">Drinks</option>
<option value="alcoholic">Alcoholic Drinks</option>
<option value="non-alcoholic">Non-Alcoholic Drinks</option>
<option value="found">Found Recipes</option>
<option value="user">User Recipes</option>
</select>
</div>
<div class="search-group">
<input
type="text"
v-model="searchQuery"
placeholder="Search recipes..."
@input="filterRecipes"
/>
</div>
</div>
<div class="recipes-grid">
<div
v-for="recipe in filteredRecipes"
:key="recipe.id"
class="recipe-card"
>
<img v-if="recipe.image" :src="recipe.image" alt="Recipe Image" />
<h3>{{ recipe.name }}</h3>
<p><strong>Type:</strong> {{ recipe.type }}</p>
<p><strong>Made By:</strong> {{ recipe.madeBy }}</p>
<p>{{ recipe.description }}</p>
</div>
</div>
<!-- Add Recipe Modal -->
<div v-if="showAddModal" class="modal-overlay" @click="closeModal">
<div class="modal-content" @click.stop>
<h2>Add Recipe</h2>
<form @submit.prevent="addRecipe">
<input v-model="newRecipe.name" type="text" placeholder="Recipe Name" required />
<textarea
v-model="newRecipe.description"
placeholder="Recipe Description"
required
></textarea>
<select v-model="newRecipe.type" required>
<option value="">Select Type</option>
<option value="appetizer">Appetizer</option>
<option value="drink">Drink</option>
<option value="alcoholic">Alcoholic Drink</option>
<option value="non-alcoholic">Non-Alcoholic Drink</option>
<option value="found">Found Recipe</option>
<option value="user">User Recipe</option>
</select>
<input
v-model="newRecipe.madeBy"
type="text"
placeholder="Made By (or Found)"
/>
<input type="file" @change="onFileChange" />
<button type="submit">Add Recipe</button>
</form>
<button @click="closeModal" class="close-button">Close</button>
</div>
</div>
<!-- Add Recipe Button -->
<button v-if="canAddRecipe" @click="showAddModal = true" class="add-button">
Add Recipe
</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { getRecipes, addRecipeToDb } from "@/recipeService"; // Replace with actual service paths
export default defineComponent({
data() {
return {
recipes: [],
filteredRecipes: [],
selectedType: "",
searchQuery: "",
showAddModal: false,
newRecipe: {
name: "",
description: "",
type: "",
madeBy: "",
image: null,
},
};
},
computed: {
canAddRecipe() {
// Replace with actual permission check logic
return localStorage.getItem("token"); // Simple check if the user is logged in
},
},
methods: {
async fetchRecipes() {
try {
const response = await getRecipes();
this.recipes = response.data;
this.filteredRecipes = this.recipes;
} catch (err) {
console.error("Failed to fetch recipes:", err);
}
},
filterRecipes() {
this.filteredRecipes = this.recipes.filter((recipe) => {
const matchesType =
!this.selectedType || recipe.type === this.selectedType;
const matchesSearch =
!this.searchQuery ||
recipe.name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
recipe.description
.toLowerCase()
.includes(this.searchQuery.toLowerCase());
return matchesType && matchesSearch;
});
},
onFileChange(event: Event) {
const file = (event.target as HTMLInputElement).files?.[0];
if (file) {
this.newRecipe.image = file;
}
},
async addRecipe() {
try {
const formData = new FormData();
formData.append("name", this.newRecipe.name);
formData.append("description", this.newRecipe.description);
formData.append("type", this.newRecipe.type);
formData.append("madeBy", this.newRecipe.madeBy || "Unknown");
if (this.newRecipe.image) {
formData.append("image", this.newRecipe.image);
}
await addRecipeToDb(formData);
this.showAddModal = false;
this.newRecipe = {
name: "",
description: "",
type: "",
madeBy: "",
image: null,
};
await this.fetchRecipes();
} catch (err) {
console.error("Failed to add recipe:", err);
}
},
closeModal() {
this.showAddModal = false;
},
},
mounted() {
this.fetchRecipes();
},
});
</script>
<style scoped>
.recipes {
padding: 2rem;
}
.filter-bar {
display: flex;
justify-content: space-between;
margin-bottom: 1rem;
}
.filter-group {
display: flex;
align-items: center;
}
.filter-group select {
margin-left: 0.5rem;
}
.search-group input {
padding: 0.5rem;
width: 100%;
max-width: 300px;
border-radius: 4px;
border: 1px solid #ccc;
}
.recipes-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
.recipe-card {
background: #313244;
padding: 1rem;
border-radius: 8px;
text-align: center;
}
.recipe-card img {
max-width: 100%;
border-radius: 8px;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
background: #1e1e2e;
padding: 2rem;
border-radius: 8px;
max-width: 600px;
width: 90%;
text-align: center;
}
.add-button {
position: fixed;
bottom: 1rem;
right: 1rem;
background: #89b4fa;
color: white;
border: none;
padding: 1rem;
border-radius: 50%;
cursor: pointer;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}
.add-button:hover {
background: #74a8e0;
}
</style>

View file

@ -1,52 +0,0 @@
<template>
<div class="register">
<h1>Register</h1>
<form @submit.prevent="handleRegister">
<input v-model="username" type="text" placeholder="Username" required />
<input v-model="password" type="password" placeholder="Password" required />
<input v-model="confirmPassword" type="password" placeholder="Confirm Password" required />
<button type="submit">Register</button>
</form>
<p v-if="error" class="error">{{ error }}</p>
<p v-if="success" class="success">{{ success }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { register } from "@/authService";
export default defineComponent({
data() {
return {
username: "",
password: "",
confirmPassword: "",
error: "",
success: "",
};
},
methods: {
async handleRegister() {
if (this.password !== this.confirmPassword) {
this.error = "Passwords do not match";
this.success = "";
return;
}
try {
await register(this.username, this.password);
this.success = "Registration successful! You can now log in.";
this.error = "";
this.username = "";
this.password = "";
this.confirmPassword = "";
} catch (err) {
this.error = "Registration failed. Please try again.";
this.success = "";
console.error(err);
}
},
},
});
</script>