Implement Password Grant Flow for Authentication and Enhance User Experience
- Introduced Password Grant Flow for user authentication, allowing direct login with email and password. - Updated `useAuth` composable to manage login and logout processes, including Single Sign-Out from Cidaas. - Enhanced user interface with a new `UserMenu` component displaying user information and logout functionality. - Updated homepage to show personalized greetings for logged-in users and a login prompt for guests. - Added logout confirmation page with a countdown redirect to the homepage. - Documented the implementation details and future enhancements for OAuth2 flows in CLAUDE.md and other relevant documentation. - Added test credentials and guidelines for automated testing in the new TESTING.md file.
This commit is contained in:
22
app/components/ui/avatar/Avatar.vue
Normal file
22
app/components/ui/avatar/Avatar.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import type { AvatarVariants } from "."
|
||||
import { AvatarRoot } from "reka-ui"
|
||||
import { cn } from '~/lib/utils'
|
||||
import { avatarVariant } from "."
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
class?: HTMLAttributes["class"]
|
||||
size?: AvatarVariants["size"]
|
||||
shape?: AvatarVariants["shape"]
|
||||
}>(), {
|
||||
size: "sm",
|
||||
shape: "circle",
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
|
||||
<slot />
|
||||
</AvatarRoot>
|
||||
</template>
|
||||
12
app/components/ui/avatar/AvatarFallback.vue
Normal file
12
app/components/ui/avatar/AvatarFallback.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarFallbackProps } from "reka-ui"
|
||||
import { AvatarFallback } from "reka-ui"
|
||||
|
||||
const props = defineProps<AvatarFallbackProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarFallback v-bind="props">
|
||||
<slot />
|
||||
</AvatarFallback>
|
||||
</template>
|
||||
12
app/components/ui/avatar/AvatarImage.vue
Normal file
12
app/components/ui/avatar/AvatarImage.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarImageProps } from "reka-ui"
|
||||
import { AvatarImage } from "reka-ui"
|
||||
|
||||
const props = defineProps<AvatarImageProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarImage v-bind="props" class="h-full w-full object-cover">
|
||||
<slot />
|
||||
</AvatarImage>
|
||||
</template>
|
||||
25
app/components/ui/avatar/index.ts
Normal file
25
app/components/ui/avatar/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
export { default as Avatar } from "./Avatar.vue"
|
||||
export { default as AvatarFallback } from "./AvatarFallback.vue"
|
||||
export { default as AvatarImage } from "./AvatarImage.vue"
|
||||
|
||||
export const avatarVariant = cva(
|
||||
"inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden",
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
sm: "h-10 w-10 text-xs",
|
||||
base: "h-16 w-16 text-2xl",
|
||||
lg: "h-32 w-32 text-5xl",
|
||||
},
|
||||
shape: {
|
||||
circle: "rounded-full",
|
||||
square: "rounded-md",
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
export type AvatarVariants = VariantProps<typeof avatarVariant>
|
||||
Reference in New Issue
Block a user