Initial Version

This commit is contained in:
root
2025-12-21 10:09:54 -05:00
commit 4ae6befc7b
422 changed files with 47225 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
/**
* Core composables - reusable composition functions
*/
export { useClipboard } from './useClipboard'
export { useUser } from './useUser'

View File

@@ -0,0 +1,45 @@
import { ref } from 'vue'
/**
* Composable for clipboard operations with visual feedback
*
* @param timeout - Duration in ms to show success state (default: 2000)
* @returns Object containing copiedKey ref and copyToClipboard function
*
* @example
* ```vue
* <script setup>
* import { useClipboard } from '@KTXC/composables/useClipboard'
*
* const { copiedKey, copyToClipboard } = useClipboard()
* </script>
*
* <template>
* <v-btn
* :icon="copiedKey === index ? 'mdi-check' : 'mdi-content-copy'"
* :color="copiedKey === index ? 'success' : undefined"
* @click="copyToClipboard(text, index)"
* />
* </template>
* ```
*/
export function useClipboard<T = number>(timeout = 2000) {
const copiedKey = ref<T | null>(null)
const copyToClipboard = async (text: string, key: T): Promise<boolean> => {
try {
await navigator.clipboard.writeText(text)
copiedKey.value = key
setTimeout(() => { copiedKey.value = null }, timeout)
return true
} catch (err) {
console.error('Failed to copy to clipboard:', err)
return false
}
}
return {
copiedKey,
copyToClipboard
}
}

View File

@@ -0,0 +1,38 @@
/**
* Simple snackbar/toast notification composable
* Uses Vuetify's snackbar component
*/
import { ref } from 'vue'
export interface SnackbarOptions {
message: string
color?: 'success' | 'error' | 'warning' | 'info' | string
timeout?: number
}
const snackbarVisible = ref(false)
const snackbarMessage = ref('')
const snackbarColor = ref<string>('info')
const snackbarTimeout = ref(3000)
export function useSnackbar() {
const showSnackbar = (options: SnackbarOptions) => {
snackbarMessage.value = options.message
snackbarColor.value = options.color || 'info'
snackbarTimeout.value = options.timeout || 3000
snackbarVisible.value = true
}
const hideSnackbar = () => {
snackbarVisible.value = false
}
return {
snackbarVisible,
snackbarMessage,
snackbarColor,
snackbarTimeout,
showSnackbar,
hideSnackbar,
}
}

View File

@@ -0,0 +1,103 @@
import { computed } from 'vue';
import { useUserStore } from '@KTXC/stores/userStore';
/**
* Composable for accessing user authentication, profile, and settings
* Provides a clean API for modules to access user data
*/
export function useUser() {
const store = useUserStore();
// =========================================================================
// Authentication
// =========================================================================
const isAuthenticated = computed(() => store.isAuthenticated);
const identifier = computed(() => store.identifier);
const identity = computed(() => store.identity);
const label = computed(() => store.label);
const roles = computed(() => store.roles);
const permissions = computed(() => store.permissions);
const hasPermission = (permission: string): boolean => {
return store.hasPermission(permission);
};
const hasAnyPermission = (perms: string[]): boolean => {
return store.hasAnyPermission(perms);
};
const hasAllPermissions = (perms: string[]): boolean => {
return store.hasAllPermissions(perms);
};
const hasRole = (role: string): boolean => {
return store.hasRole(role);
};
const logout = async (): Promise<void> => {
await store.logout();
};
// =========================================================================
// Profile
// =========================================================================
const profile = computed(() => store.profileFields);
const editableProfile = computed(() => store.editableProfileFields);
const managedProfile = computed(() => store.managedProfileFields);
const getProfile = (key: string): any => {
return store.getProfileField(key);
};
const setProfile = (key: string, value: any): boolean => {
return store.setProfileField(key, value);
};
const isProfileEditable = (key: string): boolean => {
return store.isProfileFieldEditable(key);
};
// =========================================================================
// Settings
// =========================================================================
const settings = computed(() => store.settings);
const getSetting = (key: string): any => {
return store.getSetting(key);
};
const setSetting = (key: string, value: any): void => {
store.setSetting(key, value);
};
return {
// Auth
isAuthenticated,
identifier,
identity,
label,
roles,
permissions,
hasPermission,
hasAnyPermission,
hasAllPermissions,
hasRole,
logout,
// Profile
profile,
editableProfile,
managedProfile,
getProfile,
setProfile,
isProfileEditable,
// Settings
settings,
getSetting,
setSetting,
};
}