mirror of
https://github.com/KevinMidboe/seasoned.git
synced 2026-03-11 11:55:38 +00:00
* include credentials on login fetch requests, allows set header response * Add theme composable and utility improvements - Create useTheme composable for centralized theme management - Update main.ts to use useTheme for initialization - Generalize getCookie utility in user module - Add utility functions for data formatting * Add Plex integration composables and icons - Create usePlexAuth composable for Plex OAuth flow - Create usePlexApi composable for Plex API interactions - Create useRandomWords composable for password generation - Add Plex-related icons (IconPlex, IconServer, IconSync) - Add Plex helper utilities - Update API with Plex-related endpoints * Add storage management components for data & privacy section - Create StorageManager component for browser storage overview - Create StorageSectionBrowser for localStorage/sessionStorage/cookies - Create StorageSectionServer for server-side data (mock) - Create ExportSection for data export functionality - Refactor DataExport component with modular sections - Add storage icons (IconCookie, IconDatabase, IconTimer) - Implement collapsible sections with visual indicators - Add colored borders per storage type - Display item counts and total size in headers * Add theme, password, and security settings components - Create ThemePreferences with visual theme selector - Create PasswordGenerator with passphrase and random modes - Create SecuritySettings wrapper for password management - Update ChangePassword to work with new layout - Implement improved slider UX with visual feedback - Add theme preview cards with gradients - Standardize component styling and typography * Add Plex settings and authentication components - Create PlexSettings component for Plex account management - Create PlexAuthButton with improved OAuth flow - Create PlexServerInfo for server details display - Use icon components instead of inline SVGs - Add sync and unlink functionality - Implement user-friendly authentication flow * Redesign settings page with two-column layout and ProfileHero - Create ProfileHero component with avatar and user info - Create RequestHistory component for Plex requests (placeholder) - Redesign SettingsPage with modern two-column grid layout - Add shared-settings.scss for consistent styling - Organize sections: Appearance, Security, Integrations, Data & Privacy - Implement responsive mobile layout - Standardize typography (h2: 1.5rem, 700 weight) - Add compact modifier for tighter sections
148 lines
3.8 KiB
Vue
148 lines
3.8 KiB
Vue
<template>
|
|
<div class="change-password">
|
|
<div class="password-card">
|
|
<form class="password-form" @submit.prevent>
|
|
<seasoned-input
|
|
v-model="oldPassword"
|
|
placeholder="Current password"
|
|
icon="Keyhole"
|
|
type="password"
|
|
/>
|
|
|
|
<div class="password-generator">
|
|
<button class="generator-toggle" @click="toggleGenerator">
|
|
<IconKey class="toggle-icon" />
|
|
<span>{{
|
|
showGenerator ? "Hide" : "Generate Strong Password"
|
|
}}</span>
|
|
</button>
|
|
<div v-if="showGenerator">
|
|
<password-generator @password-generated="handleGeneratedPassword" />
|
|
</div>
|
|
</div>
|
|
|
|
<seasoned-input
|
|
v-model="newPassword"
|
|
placeholder="New password"
|
|
icon="Keyhole"
|
|
type="password"
|
|
/>
|
|
|
|
<seasoned-input
|
|
v-model="newPasswordRepeat"
|
|
placeholder="Confirm new password"
|
|
icon="Keyhole"
|
|
type="password"
|
|
/>
|
|
|
|
<seasoned-button @click="changePassword" :disabled="loading">
|
|
{{ loading ? "Updating..." : "Change Password" }}
|
|
</seasoned-button>
|
|
</form>
|
|
<seasoned-messages v-model:messages="messages" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from "vue";
|
|
import SeasonedInput from "@/components/ui/SeasonedInput.vue";
|
|
import SeasonedButton from "@/components/ui/SeasonedButton.vue";
|
|
import SeasonedMessages from "@/components/ui/SeasonedMessages.vue";
|
|
import PasswordGenerator from "@/components/settings/PasswordGenerator.vue";
|
|
import IconKey from "@/icons/IconKey.vue";
|
|
import type { Ref } from "vue";
|
|
import { ErrorMessageTypes } from "../../interfaces/IErrorMessage";
|
|
import type { IErrorMessage } from "../../interfaces/IErrorMessage";
|
|
|
|
const showGenerator = ref(false);
|
|
const oldPassword: Ref<string> = ref("");
|
|
const newPassword: Ref<string> = ref("");
|
|
const newPasswordRepeat: Ref<string> = ref("");
|
|
const messages: Ref<IErrorMessage[]> = ref([]);
|
|
const loading = ref(false);
|
|
|
|
function handleGeneratedPassword(password: string) {
|
|
newPassword.value = password;
|
|
newPasswordRepeat.value = password;
|
|
}
|
|
|
|
async function changePassword(event: CustomEvent) {
|
|
try {
|
|
messages.value.push({
|
|
message: "Password change is currently disabled",
|
|
title: "Feature Disabled",
|
|
type: ErrorMessageTypes.Warning
|
|
} as IErrorMessage);
|
|
|
|
// Clear form
|
|
oldPassword.value = "";
|
|
newPassword.value = "";
|
|
newPasswordRepeat.value = "";
|
|
|
|
loading.value = false;
|
|
} catch (error) {
|
|
console.log("not valid! error:", error); // eslint-disable-line no-console
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
function toggleGenerator() {
|
|
showGenerator.value = !showGenerator.value;
|
|
/*
|
|
if (showGenerator.value && !generatedPassword.value) {
|
|
generateWordsPassword();
|
|
}
|
|
*/
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "scss/variables";
|
|
@import "scss/media-queries";
|
|
|
|
.password-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.password-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.generator-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
width: 100%;
|
|
padding: 0.75rem 1rem;
|
|
background-color: var(--background-ui);
|
|
border: 1px solid var(--background-40);
|
|
border-radius: 0.5rem;
|
|
color: $text-color;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
font-size: 0.9rem;
|
|
|
|
&:hover {
|
|
background-color: var(--background-40);
|
|
border-color: var(--highlight-color);
|
|
}
|
|
}
|
|
|
|
.toggle-icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
fill: var(--highlight-color);
|
|
}
|
|
|
|
.btn-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
fill: currentColor;
|
|
}
|
|
</style>
|