This commit is contained in:
Juhász Ervin 2025-12-26 11:46:24 +01:00
parent 76d6e30878
commit 5629a480f7
11 changed files with 184 additions and 38 deletions

View File

@ -39,4 +39,9 @@
1766434090- 25:55
1766435988- 26:44
1766438813- 3:31
1766505127-178:25
1766505127-209:24
1766523797-241:53
1766567819-999:59
1766627818- 5:26
1766745865- 1:03
1766745972- 0:00

View File

@ -14,13 +14,17 @@ const categoriesStore = useCategoriesStore()
const placeStore = useMyPlacesStore()
const authStore = useAuthStore()
const configStore = useMyConfigStore()
const token = useCookie('_auth')
const { loadToken, getToken } = useAuthToken()
async function loadData() {
// Először betöltjük a tokent (natív appnál Preferences-ből)
await loadToken()
const token = getToken()
const { data } = await useFetch('https://olcsoberauto.hu/rest/init',
{
headers: {
'auth-key': token.value
'auth-key': token || ''
}
}
)

View File

@ -7,16 +7,13 @@ const config: CapacitorConfig = {
plugins: {
SplashScreen: {
launchShowDuration: 2000,
launchAutoHide: false,
launchAutoHide: true,
backgroundColor: '#262626',
androidScaleType: 'CENTER_CROP',
showSpinner: false,
splashFullScreen: true,
splashImmersive: true
showSpinner: false
},
StatusBar: {
style: 'DARK',
backgroundColor: '#262626'
overlaysWebView: false
}
},
android: {

View File

@ -0,0 +1,80 @@
const AUTH_KEY = '_auth'
// Platform ellenőrzés - csak kliens oldalon
const isNative = (): boolean => {
if (typeof window === 'undefined') return false
try {
const { Capacitor } = require('@capacitor/core')
return Capacitor.isNativePlatform()
} catch {
return false
}
}
export const useAuthToken = () => {
const token = ref<string | null>(null)
const isLoaded = ref(false)
// Token betöltése
const loadToken = async (): Promise<string | null> => {
// SSR esetén ne csináljunk semmit
if (typeof window === 'undefined') {
return null
}
if (isNative()) {
// Natív app: Preferences használata
const { Preferences } = await import('@capacitor/preferences')
const { value } = await Preferences.get({ key: AUTH_KEY })
token.value = value
} else {
// Web: Cookie használata
const cookie = useCookie(AUTH_KEY)
token.value = cookie.value || null
}
isLoaded.value = true
return token.value
}
// Token mentése
const setToken = async (newToken: string): Promise<void> => {
if (typeof window === 'undefined') return
token.value = newToken
if (isNative()) {
const { Preferences } = await import('@capacitor/preferences')
await Preferences.set({ key: AUTH_KEY, value: newToken })
} else {
const cookie = useCookie(AUTH_KEY, { maxAge: 60 * 60 * 24 * 365 }) // 1 év
cookie.value = newToken
}
}
// Token törlése (kijelentkezés)
const clearToken = async (): Promise<void> => {
if (typeof window === 'undefined') return
token.value = null
if (isNative()) {
const { Preferences } = await import('@capacitor/preferences')
await Preferences.remove({ key: AUTH_KEY })
} else {
const cookie = useCookie(AUTH_KEY)
cookie.value = null
}
}
// Getter a token értékhez
const getToken = (): string | null => {
return token.value
}
return {
token: readonly(token),
isLoaded: readonly(isLoaded),
loadToken,
setToken,
clearToken,
getToken
}
}

View File

@ -1,8 +1,8 @@
{
"name": "nuxt-app",
"type": "module",
"version": "1.0.1",
"versionCode": 2,
"version": "1.0.2",
"versionCode": 3,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
@ -35,6 +35,7 @@
"@capacitor/core": "^8.0.0",
"@capacitor/haptics": "^8.0.0",
"@capacitor/ios": "^8.0.0",
"@capacitor/preferences": "^8.0.0",
"@capacitor/splash-screen": "^8.0.0",
"@capacitor/status-bar": "^8.0.0",
"primeicons": "^7.0.0",

View File

@ -1,6 +1,7 @@
<script lang="ts" setup>
const auth = useAuthStore()
const { setToken, loadToken, getToken } = useAuthToken()
const loginCode = ref()
const loginCodePrefix = ref()
@ -11,7 +12,7 @@ const charcode = ref()
const errorMessage = ref()
const successMessage = ref()
const router = useRouter()
const token = useCookie('_auth')
async function sendCode() {
isLoading.value = true
errorMessage.value = false
@ -34,7 +35,7 @@ async function sendCode() {
successMessage.value = data.value?.message
}
if (data.value?.token) {
token.value = data.value.token
await setToken(data.value.token)
window.localStorage.removeItem('codePrefix')
window.localStorage.removeItem('codeExpire')
if (data.value?.user) {
@ -61,7 +62,14 @@ function changeCode() {
}
}
onMounted(()=>{
onMounted(async () => {
// Ha már be van jelentkezve, irányítsuk a főoldalra
await loadToken()
const token = getToken()
if (token) {
return navigateTo('/')
}
loginCodePrefix.value = window.localStorage.getItem('codePrefix')
codeExpire.value = window.localStorage.getItem('codeExpire')
account.value = window.localStorage.getItem('account')

View File

@ -67,7 +67,15 @@ async function sendAccount() {
isLoading.value = false
}
onMounted(() => {
onMounted(async () => {
// Ha már be van jelentkezve, irányítsuk a főoldalra
const { loadToken, getToken } = useAuthToken()
await loadToken()
const token = getToken()
if (token) {
return navigateTo('/')
}
account.value = window.localStorage.getItem('account')
})

View File

@ -80,6 +80,9 @@
<Button @click="save()" class="w-full min-w-20" icon="pi pi-save">Adatok mentése</Button>
</div>
<pre>{{ rent }}</pre>
<div class="pt-6 border-t border-surface-200 dark:border-surface-700">
<Button @click="logout()" severity="danger" class="w-full" icon="pi pi-sign-out">Kijelentkezés</Button>
</div>
</div>
</div>
</template>
@ -87,7 +90,9 @@
<script lang="ts" setup>
const isLoading = ref(false)
const sameAddress = ref(true)
const { user, rent } = storeToRefs(useAuthStore())
const authStore = useAuthStore()
const { user, rent } = storeToRefs(authStore)
const { getToken } = useAuthToken()
const showDialog = ref(false)
const dialogType = ref<'success' | 'error'>('success')
const dialogMessage = ref('')
@ -118,11 +123,11 @@ const hasAllRequiredData = computed(() => {
async function save() {
isLoading.value = true
const token = useCookie('_auth')
const token = getToken()
const data = await $fetch<{ success: boolean; message: string }>('https://olcsoberauto.hu/rest/update_profile',
{
headers: {
'auth-key': token.value || ''
'auth-key': token || ''
},
method: 'POST',
body: {
@ -142,6 +147,10 @@ async function save() {
}
showDialog.value = true
}
async function logout() {
await authStore.logout()
}
</script>
<style></style>

View File

@ -18,21 +18,24 @@ export default defineNuxtPlugin((nuxtApp) => {
if (router.currentRoute.value.path !== '/' && window.history.length > 1) {
router.back()
} else {
// Ha a főoldalon vagyunk, kérdezzük meg hogy ki akar-e lépni
// vagy minimalizáljuk az appot
// Ha a főoldalon vagyunk, minimalizáljuk az appot
App.minimizeApp()
}
})
// Status bar beállítása
const setupStatusBar = async () => {
// Status bar beállítása dark/light mode alapján
const setupStatusBar = async (isDark: boolean) => {
try {
// Sötét ikonok világos háttérrel (vagy fordítva dark mode-ban)
await StatusBar.setStyle({ style: Style.Dark })
// Android-on beállíthatjuk a háttérszínt
if (Capacitor.getPlatform() === 'android') {
await StatusBar.setBackgroundColor({ color: '#262626' }) // neutral-800
if (isDark) {
// Dark mode: sötét háttér, világos ikonok
await StatusBar.setBackgroundColor({ color: '#0a0a0a' }) // surface-950
await StatusBar.setStyle({ style: Style.Dark }) // világos ikonok
} else {
// Light mode: világos háttér, sötét ikonok
await StatusBar.setBackgroundColor({ color: '#fafafa' }) // surface-50
await StatusBar.setStyle({ style: Style.Light }) // sötét ikonok
}
}
} catch (e) {
console.warn('StatusBar setup error:', e)
@ -50,9 +53,18 @@ export default defineNuxtPlugin((nuxtApp) => {
}
}
// Dark mode figyelése
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
// Dark mode változás figyelése
darkModeQuery.addEventListener('change', (e) => {
setupStatusBar(e.matches)
})
// App mounted hook
nuxtApp.hooks.hook('app:mounted', async () => {
await setupStatusBar()
// Kezdeti beállítás a jelenlegi dark mode állapot alapján
await setupStatusBar(darkModeQuery.matches)
// Kis késleltetés hogy a UI renderelődjön
setTimeout(() => {
hideSplash()

View File

@ -23,6 +23,9 @@ importers:
'@capacitor/ios':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.0)
'@capacitor/preferences':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.0)
'@capacitor/splash-screen':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.0)
@ -74,7 +77,7 @@ importers:
version: 10.4.23(postcss@8.5.6)
nuxt:
specifier: 3.15.0
version: 3.15.0(@parcel/watcher@2.5.1)(@types/node@25.0.3)(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(rollup@4.54.0)(terser@5.44.1)(typescript@5.9.3)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2)
version: 3.15.0(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(@parcel/watcher@2.5.1)(@types/node@25.0.3)(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(rollup@4.54.0)(terser@5.44.1)(typescript@5.9.3)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2)
pinia:
specifier: ^2.3.1
version: 2.3.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))
@ -681,6 +684,11 @@ packages:
peerDependencies:
'@capacitor/core': ^8.0.0
'@capacitor/preferences@8.0.0':
resolution: {integrity: sha512-NsE7Srk9Zr0SxiVelHGiAJR7M238eyCD6dI/sDhu3ckKwFrXn8/GRyGr+SZcnGLlQKy948li8Pfcfr0dqxNf1g==}
peerDependencies:
'@capacitor/core': '>=8.0.0'
'@capacitor/splash-screen@8.0.0':
resolution: {integrity: sha512-zkFdUSd6C6gd3s3bIEgtO3DVjfwpaX5mmWU9er8xYTg47zr2toEkGtfyE6CPhhErG09fl4rCqrK5DfnGrXLh9w==}
peerDependencies:
@ -6640,6 +6648,10 @@ snapshots:
dependencies:
'@capacitor/core': 8.0.0
'@capacitor/preferences@8.0.0(@capacitor/core@8.0.0)':
dependencies:
'@capacitor/core': 8.0.0
'@capacitor/splash-screen@8.0.0(@capacitor/core@8.0.0)':
dependencies:
'@capacitor/core': 8.0.0
@ -10242,7 +10254,7 @@ snapshots:
neo-async@2.6.2: {}
nitropack@2.12.9(xml2js@0.6.2):
nitropack@2.12.9(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(xml2js@0.6.2):
dependencies:
'@cloudflare/kv-asset-handler': 0.4.1
'@rollup/plugin-alias': 5.1.1(rollup@4.54.0)
@ -10309,7 +10321,7 @@ snapshots:
unenv: 2.0.0-rc.24
unimport: 5.6.0
unplugin-utils: 0.3.1
unstorage: 1.17.3(db0@0.3.4)(ioredis@5.8.2)
unstorage: 1.17.3(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(db0@0.3.4)(ioredis@5.8.2)
untyped: 2.0.0
unwasm: 0.3.11
youch: 4.1.0-beta.13
@ -10407,7 +10419,7 @@ snapshots:
nuxi@3.31.3: {}
nuxt@3.15.0(@parcel/watcher@2.5.1)(@types/node@25.0.3)(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(rollup@4.54.0)(terser@5.44.1)(typescript@5.9.3)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2):
nuxt@3.15.0(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(@parcel/watcher@2.5.1)(@types/node@25.0.3)(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(rollup@4.54.0)(terser@5.44.1)(typescript@5.9.3)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2):
dependencies:
'@nuxt/devalue': 2.0.2
'@nuxt/devtools': 1.7.0(rollup@4.54.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
@ -10444,7 +10456,7 @@ snapshots:
magic-string: 0.30.21
mlly: 1.8.0
nanotar: 0.1.1
nitropack: 2.12.9(xml2js@0.6.2)
nitropack: 2.12.9(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(xml2js@0.6.2)
nuxi: 3.31.3
nypm: 0.4.1
ofetch: 1.5.1
@ -10467,7 +10479,7 @@ snapshots:
unimport: 3.14.6(rollup@4.54.0)
unplugin: 2.3.11
unplugin-vue-router: 0.10.9(rollup@4.54.0)(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
unstorage: 1.17.3(db0@0.3.4)(ioredis@5.8.2)
unstorage: 1.17.3(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(db0@0.3.4)(ioredis@5.8.2)
untyped: 1.5.2
vue: 3.5.26(typescript@5.9.3)
vue-bundle-renderer: 2.2.0
@ -12057,7 +12069,7 @@ snapshots:
picomatch: 4.0.3
webpack-virtual-modules: 0.6.2
unstorage@1.17.3(db0@0.3.4)(ioredis@5.8.2):
unstorage@1.17.3(@capacitor/preferences@8.0.0(@capacitor/core@8.0.0))(db0@0.3.4)(ioredis@5.8.2):
dependencies:
anymatch: 3.1.3
chokidar: 4.0.3
@ -12068,6 +12080,7 @@ snapshots:
ofetch: 1.5.1
ufo: 1.6.1
optionalDependencies:
'@capacitor/preferences': 8.0.0(@capacitor/core@8.0.0)
db0: 0.3.4
ioredis: 5.8.2

View File

@ -5,12 +5,13 @@ export const useAuthStore = defineStore({
state: () => ({ user: null, rentals: null, rent: {} }),
actions: {
async getData() {
const token = useCookie('_auth')
if (token.value) {
const { getToken } = useAuthToken()
const token = getToken()
if (token) {
const { data } = await useFetch('https://olcsoberauto.hu/rest/me',
{
headers: {
'auth-key': token.value
'auth-key': token
}
}
)
@ -20,6 +21,14 @@ export const useAuthStore = defineStore({
this.rentals = data.value.rentals
}
}
},
async logout() {
const { clearToken } = useAuthToken()
await clearToken()
this.user = null
this.rentals = null
this.rent = {}
navigateTo('/login')
}
}
})