Skip to content

Commit 4052bae

Browse files
authored
Merge pull request #126 from BacktrackAcademy/patch-minor
Patch minor
2 parents 73189e6 + b2ddba6 commit 4052bae

File tree

9 files changed

+405
-201
lines changed

9 files changed

+405
-201
lines changed

components/MultiSelect.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ import { cn } from '@/lib/utils'
66
import { X } from 'lucide-vue-next'
77
import { computed, ref } from 'vue'
88
9+
interface Option {
10+
value: string
11+
label: string
12+
}
13+
914
// Definición de las props
1015
const props = defineProps<{
11-
options: { value: string, label: string }[]
16+
options: Option[]
1217
selected: string[]
1318
placeholder?: string
1419
searchPlaceholder?: string

components/auth/UserAuthForm.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function handleSubmit() {
3535
<input
3636
id="email"
3737
v-model="userInfo.email"
38-
class="pl-2 outline-none border-none w-full"
38+
class="pl-2 outline-none border-none w-full text-secondary"
3939
type="email"
4040
placeholder="mail@example.com"
4141
required
@@ -54,7 +54,7 @@ function handleSubmit() {
5454
<input
5555
id="password"
5656
v-model="userInfo.password"
57-
class="pl-2 outline-none border-none w-full"
57+
class="pl-2 outline-none border-none w-full text-secondary"
5858
:type="showPassword ? 'text' : 'password'"
5959
placeholder="Ingresar contraseña"
6060
required
Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
<script setup lang="ts">
2-
interface Course {
3-
slug: string
4-
image_thumb: string
5-
titulo: string
6-
shortdes: string
7-
total_duration_text: string
8-
price: number | null
9-
}
2+
import type { Course } from '~/interfaces/courses.response'
103
114
defineProps<{ course: Course }>()
5+
6+
const { convertToHours } = useFormatter()
127
</script>
138

149
<template>
@@ -30,7 +25,7 @@ defineProps<{ course: Course }>()
3025
>
3126
</figure>
3227
<!-- Card Content -->
33-
<div class="flex-grow flex flex-col p-5">
28+
<div class="flex-grow flex flex-col p-4">
3429
<!-- Card body -->
3530
<div class="flex-grow">
3631
<!-- Header -->
@@ -57,12 +52,18 @@ defineProps<{ course: Course }>()
5752
<!-- Card footer -->
5853
<div class="flex justify-between items-center">
5954
<p class="font-inconsolata text-sm text-gray-400">
60-
{{ course.total_duration_text }}
55+
{{ convertToHours(course.total_duration_text) }}
6156
</p>
62-
<div v-if="course.price === 0 || course.price === null" class="font-semibold text-sm inline-flex items-center justify-center px-4 py-2 rounded-lg transition-colors duration-150 ease-in-out bg-bta-pink/95 hover:bg-bta-pink text-white">
57+
<div
58+
v-if="course.price === 0 || course.price === null"
59+
class="font-semibold text-sm inline-flex items-center justify-center px-4 py-2 rounded-lg transition-all duration-300 ease-in-out bg-bta-pink/95 hover:bg-bta-pink hover:scale-105 hover:-translate-y-1 text-white"
60+
>
6361
Gratis
6462
</div>
65-
<div v-else class="font-semibold text-sm inline-flex items-center justify-center px-4 py-2 rounded-lg transition-colors duration-150 ease-in-out bg-bta-pink/95 hover:bg-bta-pink text-white">
63+
<div
64+
v-else
65+
class="font-semibold text-sm inline-flex items-center justify-center px-4 py-2 rounded-lg transition-all duration-300 ease-in-out bg-bta-pink/95 hover:bg-bta-pink hover:scale-105 hover:-translate-y-1 text-white"
66+
>
6667
$ {{ course.price }}
6768
</div>
6869
</div>
@@ -106,4 +107,15 @@ defineProps<{ course: Course }>()
106107
clip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);
107108
text-shadow: 2px 0 #00fff9;
108109
}
110+
111+
/* Animación suave para el precio */
112+
.transition-all {
113+
transition-property: all;
114+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
115+
transition-duration: 300ms;
116+
}
117+
118+
.hover\:scale-105:hover {
119+
transform: scale(1.05) translateY(-0.25rem);
120+
}
109121
</style>

components/ui/input/Input.vue

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
import { useVModel } from '@vueuse/core'
5+
6+
const props = defineProps<{
7+
defaultValue?: string | number
8+
modelValue?: string | number
9+
class?: HTMLAttributes['class']
10+
}>()
11+
12+
const emits = defineEmits<{
13+
(e: 'update:modelValue', payload: string | number): void
14+
}>()
15+
16+
const modelValue = useVModel(props, 'modelValue', emits, {
17+
passive: true,
18+
defaultValue: props.defaultValue,
19+
})
20+
</script>
21+
22+
<template>
23+
<input v-model="modelValue" :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)">
24+
</template>

components/ui/input/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Input } from './Input.vue'

composables/useFormatter.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export function useFormatter() {
2+
function convertToHours(duration: string): string {
3+
// Si no hay duración, retornar un valor por defecto
4+
if (!duration)
5+
return '0h 0m'
6+
7+
// Extraer los números de la cadena y convertirlos a números
8+
const numbers = (duration.match(/\d+/g) || [])
9+
const totalMinutes = numbers.reduce((acc, curr) => acc + Number(curr), 0)
10+
11+
// Convertir minutos a horas y minutos
12+
const hours = Math.floor(totalMinutes / 60)
13+
const minutes = totalMinutes % 60
14+
15+
return `${hours ? `${hours}h` : ''} ${minutes ? `${minutes}m` : ''}`.trim() || '0h 0m'
16+
}
17+
18+
return {
19+
convertToHours,
20+
}
21+
}

interfaces/courses.response.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export interface CoursesResponse {
2+
courses: Course[]
3+
pagination: Pagination
4+
}
5+
6+
export interface Course {
7+
id: number
8+
titulo: string
9+
descripcion: string
10+
created_at: string
11+
updated_at: string
12+
user_id: number
13+
is_free: boolean
14+
shortdes: string
15+
level_id: number
16+
price: number
17+
is_active: boolean
18+
slug: string
19+
is_notified: boolean
20+
coming_soon: boolean
21+
category_id: number
22+
primary_color: string
23+
metatag: string
24+
pageviews: number
25+
students: number
26+
number_videos: number
27+
outdated: boolean
28+
timer: string
29+
total_duration_text: string
30+
total_duration_seconds: number
31+
teacher: {
32+
name: string
33+
lastname: string
34+
username: string
35+
aboutme: string
36+
ranking: number
37+
headline: string
38+
avatar_url: string
39+
avatar_url_sidebar: string
40+
}
41+
image_thumb: string
42+
level_name: string
43+
}
44+
45+
export interface Pagination {
46+
current_page: number
47+
per_page: number
48+
total_entries: number
49+
total_pages: number
50+
}

0 commit comments

Comments
 (0)