(), {
-
\ No newline at end of file
+
diff --git a/src/components/input/BaseInput.vue b/src/components/input/BaseInput.vue
index 37ffc23..0ece555 100644
--- a/src/components/input/BaseInput.vue
+++ b/src/components/input/BaseInput.vue
@@ -7,10 +7,10 @@ import { ButtonForm, ButtonMode } from '@/components/button/BaseButton.types.ts'
import { hasSlotContent } from '@/utils/helpers.ts';
interface Props {
- inputType?: InputType; /* The type of the input. @defaults InputForm.BLOCK */
- form?: InputForm; /* The form of the input. @defaults InputForm.TEXT */
+ inputType?: InputType; /* The type of the input. @defaults InputForm.TEXT */
+ form?: InputForm; /* The form of the input. @defaults InputForm.BLOCK */
hasError?: boolean; /* Indicates if the input has an error. Determines if the `error` slot will be shown */
- customValidity?: string; /* The error message of the input */
+ customValidity?: string; /* The error message of the input. It is the default value for the `error` slot */
loading?: boolean; /* Indicates if the input is loading */
isClearable?: boolean; /* Indicates if the input is clearable. @defaults true */
}
@@ -140,7 +140,7 @@ watch(() => props.hasError, (value) => {
@@ -162,6 +162,7 @@ watch(() => props.hasError, (value) => {
diff --git a/src/components/radio/BaseRadioGroup.vue b/src/components/radio/BaseRadioGroup.vue
new file mode 100644
index 0000000..0b36025
--- /dev/null
+++ b/src/components/radio/BaseRadioGroup.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+ {{ option }}
+
+
+
+
+
+
+
+
+
+ {{ customValidity }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/select/BaseSelect.vue b/src/components/select/BaseSelect.vue
index 446f976..0ba1f5a 100644
--- a/src/components/select/BaseSelect.vue
+++ b/src/components/select/BaseSelect.vue
@@ -138,7 +138,7 @@ function selectItem(item: T) {
diff --git a/src/layouts/OnboardingLayout.vue b/src/layouts/OnboardingLayout.vue
index b67517a..75842c5 100644
--- a/src/layouts/OnboardingLayout.vue
+++ b/src/layouts/OnboardingLayout.vue
@@ -15,7 +15,7 @@ import { ButtonForm, ButtonMode } from '@/components/button/BaseButton.types.ts'
Saltar
@@ -32,4 +32,4 @@ header {
padding: 8px 16px;
margin-bottom: 32px;
}
-
\ No newline at end of file
+
diff --git a/src/modules/app/components/ErrorMessage.vue b/src/modules/app/components/ErrorMessage.vue
new file mode 100644
index 0000000..b1a80ee
--- /dev/null
+++ b/src/modules/app/components/ErrorMessage.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/src/modules/app/components/TheHeader.vue b/src/modules/app/components/TheHeader.vue
new file mode 100644
index 0000000..fad786d
--- /dev/null
+++ b/src/modules/app/components/TheHeader.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+ {{ title }}
+
+
+ $emit('clickAction')"
+ >
+ {{ actionText }}
+
+
+
+
+
diff --git a/src/modules/app/composables/useDB.ts b/src/modules/app/composables/useDB.ts
index 73ca1da..88e3c44 100644
--- a/src/modules/app/composables/useDB.ts
+++ b/src/modules/app/composables/useDB.ts
@@ -6,6 +6,7 @@ import type {
} from 'firebase/firestore';
import {
Timestamp,
+ addDoc,
collection,
doc,
getDoc,
@@ -104,10 +105,9 @@ export function useDB(collectionName: string) {
const { user } = useAuth();
const collectionRef = collection(db, collectionName).withConverter(getConverter());
- const elementRef = doc(collectionRef);
if (typeof element === 'object') {
const date: Timestamp = Timestamp.now();
- await setDoc(elementRef, {
+ return await addDoc(collectionRef, {
...element,
user_uuid: user.value?.uid,
created_at: date,
@@ -123,7 +123,7 @@ export function useDB(collectionName: string) {
const elementSnap = await getDoc(elementRef);
if (elementSnap.exists() && typeof element === 'object') {
const date: Timestamp = Timestamp.now();
- await setDoc(elementRef, {
+ return await setDoc(elementRef, {
...element,
updated_at: date,
});
@@ -132,9 +132,9 @@ export function useDB(collectionName: string) {
async function upsert(element: WithFieldValue, uuid?: string) {
if (!uuid) {
- await create(element);
+ return await create(element);
} else {
- await update(element, uuid);
+ return await update(element, uuid);
}
}
diff --git a/src/modules/app/pages/HomePage.vue b/src/modules/app/pages/HomePage.vue
index b3f2d6c..438b0d8 100644
--- a/src/modules/app/pages/HomePage.vue
+++ b/src/modules/app/pages/HomePage.vue
@@ -1,34 +1,35 @@
+
Loading...
-
-
- Error
-
-
-
+
Empty
- Success
+
+ {{ people.find(p => p.id === $route.query?.created)?.name || 'ni idea' }} se ha creado!
+
+
+ {{ person }}
+
+
+
diff --git a/src/modules/onboarding/pages/OnboardingPage.vue b/src/modules/onboarding/pages/OnboardingPage.vue
index dc8f2fb..c0b5367 100644
--- a/src/modules/onboarding/pages/OnboardingPage.vue
+++ b/src/modules/onboarding/pages/OnboardingPage.vue
@@ -1,7 +1,7 @@
@@ -62,7 +61,7 @@ const stepText = computed(() => {
{{ currentStep === 3 ? 'Empezar' : 'Siguiente' }}
@@ -109,4 +108,4 @@ main {
align-items: center;
}
}
-
\ No newline at end of file
+
diff --git a/src/modules/people/composables/usePeopleService.ts b/src/modules/people/composables/usePeopleService.ts
index 12ac550..c978fed 100644
--- a/src/modules/people/composables/usePeopleService.ts
+++ b/src/modules/people/composables/usePeopleService.ts
@@ -1,20 +1,32 @@
-import { Person } from '@/modules/people/models/Person.ts';
import { ref } from 'vue';
+import type { Person } from '@/modules/people/models/Person.ts';
import { useDB } from '@/modules/app/composables/useDB.ts';
const people = ref([]);
export function usePeopleService() {
- const { getBy } = useDB('people');
-
+ const { loading, getBy, upsert } = useDB('people');
+
async function getPeople() {
people.value = [];
-
+
// Fetch people from API
people.value = await getBy();
}
-
+
+ async function createPerson(person: Person) {
+ const personRef = await upsert(person);
+ await getPeople();
+ return personRef;
+ }
+
+ if (!people.value.length) {
+ void getPeople();
+ }
+
return {
people,
+ loading,
getPeople,
- }
-}
\ No newline at end of file
+ createPerson,
+ };
+}
diff --git a/src/modules/people/models/Person.ts b/src/modules/people/models/Person.ts
index 04ea098..f25eb9d 100644
--- a/src/modules/people/models/Person.ts
+++ b/src/modules/people/models/Person.ts
@@ -1,3 +1,10 @@
export interface Person {
- id: number;
-}
\ No newline at end of file
+ id?: string;
+ name: string;
+ fatherName: string;
+ motherName: string;
+ gender: Gender;
+ notes?: string;
+}
+
+export type Gender = 'male' | 'female' | 'unknown';
diff --git a/src/modules/people/pages/PersonCreate.vue b/src/modules/people/pages/PersonCreate.vue
new file mode 100644
index 0000000..1b04b87
--- /dev/null
+++ b/src/modules/people/pages/PersonCreate.vue
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/people/pages/PersonPage.vue b/src/modules/people/pages/PersonPage.vue
new file mode 100644
index 0000000..a991ce1
--- /dev/null
+++ b/src/modules/people/pages/PersonPage.vue
@@ -0,0 +1,16 @@
+
+
+
+ {{ ID }}
+
+
+
diff --git a/src/router.ts b/src/router.ts
index 009f54b..df95a75 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -8,41 +8,53 @@ export const routes: Array = [
name: 'Login',
component: () => import('@/modules/auth/pages/LoginPage.vue'),
meta: {
- title: 'Login',
+ title: 'Iniciar sesión',
isPublic: true,
},
},
-
+
{
path: '/logout',
name: 'Logout',
component: () => import('@/modules/auth/pages/LoginPage.vue'),
- meta: { title: 'Logout' },
+ meta: {
+ title: 'Cerrar sesión',
+ isPublic: true,
+ },
beforeEnter: (to) => {
window.location.href = `/login${to.query?.redirect ? (`?redirect=${String(to.query.redirect)}`) : ''}`;
},
},
-
+
{
path: '',
name: 'Home',
component: () => import('@/modules/app/pages/HomePage.vue'),
- meta: {
- title: 'Home',
- isPublic: false,
- },
+ meta: { title: '' },
+
},
-
+
{
path: '/onboarding',
name: 'Onboarding',
component: () => import('@/modules/onboarding/pages/OnboardingPage.vue'),
- meta: {
- title: 'Onboarding',
- isPublic: false,
- },
+ meta: { title: 'Onboarding' },
},
-
+
+ {
+ path: '/people/__new__',
+ name: 'New Person',
+ component: () => import('@/modules/people/pages/PersonCreate.vue'),
+ meta: { title: 'Nueva persona' },
+ },
+
+ {
+ path: '/people/:id',
+ name: 'Person',
+ component: () => import('@/modules/people/pages/PersonPage.vue'),
+ meta: { title: '{id}' },
+ },
+
{
path: '/showcase',
name: 'Component Showcase',
@@ -52,7 +64,7 @@ export const routes: Array = [
isPublic: true,
},
},
-
+
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
@@ -62,7 +74,7 @@ export const routes: Array = [
isPublic: true,
},
},
-]
+];
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -85,14 +97,14 @@ function setDocumentTitle(to: RouteLocationNormalized) {
const titleSuffix = import.meta.env.MODE !== 'production'
? (` ${((import.meta.env.VITE_ENV_NAME as string | undefined) || import.meta.env.MODE).toUpperCase()}`)
: '';
- document.title = `${to.meta?.title ? (`${to.meta.title} | `) : ''}🧬 Genoma${titleSuffix}`;
+ document.title = `${to.meta?.title ? (`${String(to.meta.title)} | `) : ''}🧬 Genoma${titleSuffix}`;
}
async function checkAuth(to: RouteLocationNormalized) {
if (to.meta?.isPublic) {
return;
}
-
+
// TODO - This is a workaround for the firebase auth state change delay
const { loading, user } = useAuth();
if (!user.value) {
@@ -100,11 +112,10 @@ async function checkAuth(to: RouteLocationNormalized) {
await new Promise(resolve => setTimeout(resolve, 50));
}
}
-
+
if (!user.value) {
- return `/logout${to.name === 'Home' ? '' : `?unauthorized=${to.fullPath}`}`;
+ return `/logout${to.name === 'Login' ? '' : `?unauthorized=${to.fullPath}`}`;
}
}
-
-export default router
+export default router;
diff --git a/src/showcase/ShowcasePage.vue b/src/showcase/ShowcasePage.vue
index 54fe39d..a8f20d1 100644
--- a/src/showcase/ShowcasePage.vue
+++ b/src/showcase/ShowcasePage.vue
@@ -1,14 +1,20 @@
+
+
+
+
+
+ With src
+
+
+
+
+
+
+
+
+
+ Without src
+
+
+
+
+
+
+
+
+
+
diff --git a/src/showcase/sheets/RadioSheet.vue b/src/showcase/sheets/RadioSheet.vue
new file mode 100644
index 0000000..dcbf9cd
--- /dev/null
+++ b/src/showcase/sheets/RadioSheet.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ normal
+
+
+ selected: {{ selectedElement }}
+
+
+
+
+ Test 1
+
+
+
+ Test 2
+
+
+
+
+
+ group
+
+
+ selected: {{ selectedElement }}
+
+
+
+
+
+ {{ option.name }}
+
+
+
+
+
+ {{ option.name }}
+
+
+
+
+
+ {{ option.name }}
+
+
+
+ This is an error
+
+
+
+
+
+ {{ option.name }}
+
+
+
+ This is a helper
+
+
+
+
+
+
+
diff --git a/src/theme/colors.scss b/src/theme/colors.scss
index 516a6e4..80e8593 100644
--- a/src/theme/colors.scss
+++ b/src/theme/colors.scss
@@ -9,6 +9,7 @@
--color-secondary-accent: #F8F7F5;
/** Grayscale **/
+ --color-gray-0-alpha: #ffffff1A;
--color-gray-0: #ffffff;
--color-gray-1: #f2f2f2;
--color-gray-2: #e6e6e6;