@paris-ias/list 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/example/.env.example +3 -0
  2. package/example/nuxt.config.ts +19 -0
  3. package/example/pages/index.vue +27 -0
  4. package/package.json +3 -3
  5. package/src/module.ts +119 -0
  6. package/src/runtime/components/events/Badges.vue +73 -0
  7. package/src/runtime/components/events/DateTimePlace.vue +77 -0
  8. package/src/runtime/components/events/DenseItem.vue +40 -0
  9. package/src/runtime/components/events/ExpandedItem.vue +11 -0
  10. package/src/runtime/components/events/ListContainer.vue +41 -0
  11. package/src/runtime/components/events/RegisterModal.vue +51 -0
  12. package/src/runtime/components/events/RelatedItem.vue +44 -0
  13. package/src/runtime/components/events/RowsItem.vue +114 -0
  14. package/src/runtime/components/events/View.vue +333 -0
  15. package/src/runtime/components/fellowships/Badges.vue +48 -0
  16. package/src/runtime/components/fellowships/DenseItem.vue +39 -0
  17. package/src/runtime/components/fellowships/ExpandedItem.vue +7 -0
  18. package/src/runtime/components/fellowships/RegisterModal.vue +41 -0
  19. package/src/runtime/components/fellowships/RowsItem.vue +61 -0
  20. package/src/runtime/components/fellowships/View.vue +210 -0
  21. package/src/runtime/components/list/atoms/FiltersMenu.vue +46 -0
  22. package/src/runtime/components/list/atoms/SearchInput.vue +129 -0
  23. package/src/runtime/components/list/atoms/SearchItem.vue +59 -0
  24. package/src/runtime/components/list/atoms/SearchString.vue +161 -0
  25. package/src/runtime/components/list/atoms/SortMenu.vue +97 -0
  26. package/src/runtime/components/list/atoms/ViewMenu.vue +71 -0
  27. package/src/runtime/components/list/inputs/AutoComplete.vue +22 -0
  28. package/src/runtime/components/list/inputs/BooleanSwitch.vue +18 -0
  29. package/src/runtime/components/list/inputs/Checkbox.vue +21 -0
  30. package/src/runtime/components/list/inputs/Select.vue +25 -0
  31. package/src/runtime/components/list/molecules/Filters.vue +97 -0
  32. package/src/runtime/components/list/molecules/Header.vue +47 -0
  33. package/src/runtime/components/list/molecules/Pagination.vue +243 -0
  34. package/src/runtime/components/list/organisms/List.vue +92 -0
  35. package/src/runtime/components/list/views/Dense.vue +25 -0
  36. package/src/runtime/components/list/views/Expanded.vue +10 -0
  37. package/src/runtime/components/list/views/Grid.vue +13 -0
  38. package/src/runtime/components/list/views/Rows.vue +13 -0
  39. package/src/runtime/components/list/views/Table.vue +13 -0
  40. package/src/runtime/components/misc/atoms/CountUp.vue +198 -0
  41. package/src/runtime/components/misc/atoms/DateStamp.vue +104 -0
  42. package/src/runtime/components/misc/atoms/ImageContainer.vue +105 -0
  43. package/src/runtime/components/misc/atoms/ShareMenu.vue +60 -0
  44. package/src/runtime/components/misc/atoms/Socials.vue +127 -0
  45. package/src/runtime/components/misc/molecules/ChipContainer.vue +35 -0
  46. package/src/runtime/components/misc/molecules/Related.vue +41 -0
  47. package/src/runtime/components/misc/molecules/RelatedItems.vue +29 -0
  48. package/src/runtime/components/misc/molecules/SearchItem.vue +26 -0
  49. package/src/runtime/components/news/DenseItem.vue +62 -0
  50. package/src/runtime/components/news/ExpandedItem.vue +153 -0
  51. package/src/runtime/components/news/Header.vue +9 -0
  52. package/src/runtime/components/news/RelatedItem.vue +44 -0
  53. package/src/runtime/components/news/RowsItem.vue +160 -0
  54. package/src/runtime/components/news/View.vue +190 -0
  55. package/src/runtime/components/people/DenseItem.vue +37 -0
  56. package/src/runtime/components/people/ExpandedItem.vue +16 -0
  57. package/src/runtime/components/people/GroupBadges.vue +56 -0
  58. package/src/runtime/components/people/RelatedItem.vue +41 -0
  59. package/src/runtime/components/people/RowsItem.vue +95 -0
  60. package/src/runtime/components/people/View.vue +162 -0
  61. package/src/runtime/components/projects/ExpandedItem.vue +14 -0
  62. package/src/runtime/components/projects/RelatedItem.vue +44 -0
  63. package/src/runtime/components/projects/RowsItem.vue +106 -0
  64. package/src/runtime/components/projects/View.vue +131 -0
  65. package/src/runtime/components/publications/RelatedItem.vue +44 -0
  66. package/src/runtime/components/publications/RowsItem.vue +105 -0
  67. package/src/runtime/components/publications/View.vue +139 -0
  68. package/src/runtime/composables/useFetchItem.ts +64 -0
  69. package/src/runtime/composables/useIcons.ts +30 -0
  70. package/src/runtime/composables/useUtils.ts +75 -0
  71. package/src/runtime/graphql/queries/buildFiltersValues.gql +35 -0
  72. package/src/runtime/graphql/queries/item/action.gql +0 -0
  73. package/src/runtime/graphql/queries/item/apps.gql +0 -0
  74. package/src/runtime/graphql/queries/item/events.gql +120 -0
  75. package/src/runtime/graphql/queries/item/fellowships.gql +164 -0
  76. package/src/runtime/graphql/queries/item/news.gql +129 -0
  77. package/src/runtime/graphql/queries/item/people.gql +174 -0
  78. package/src/runtime/graphql/queries/item/projects.gql +171 -0
  79. package/src/runtime/graphql/queries/item/publications.gql +169 -0
  80. package/src/runtime/graphql/queries/item/users.gql +0 -0
  81. package/src/runtime/graphql/queries/list/action.gql +0 -0
  82. package/src/runtime/graphql/queries/list/apps.gql +32 -0
  83. package/src/runtime/graphql/queries/list/events.gql +44 -0
  84. package/src/runtime/graphql/queries/list/fellowships.gql +53 -0
  85. package/src/runtime/graphql/queries/list/news.gql +39 -0
  86. package/src/runtime/graphql/queries/list/people.gql +49 -0
  87. package/src/runtime/graphql/queries/list/projects.gql +37 -0
  88. package/src/runtime/graphql/queries/list/publications.gql +37 -0
  89. package/src/runtime/graphql/queries/list/search.gql +148 -0
  90. package/src/runtime/graphql/queries/list/users.gql +32 -0
  91. package/src/runtime/graphql/queries/login.gql +0 -0
  92. package/src/runtime/plugins/pinia.ts +88 -0
  93. package/src/runtime/plugins/vuetify.js +21 -0
  94. package/src/runtime/stores/factory.ts +18 -0
  95. package/src/runtime/stores/root.ts +353 -0
  96. package/src/runtime/translations/en.json +436 -0
  97. package/src/runtime/translations/fr.json +429 -0
  98. package/src/runtime/types/imports.d.ts +13 -0
  99. package/src/runtime/types/stores.d.ts +11 -0
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <v-row
3
+ v-ripple
4
+ no-gutters
5
+ class="cursor-pointer highlight-on-hover"
6
+ @click="$router.push(localePath('/people/' + item.slug))"
7
+ >
8
+ <v-col align-self="center" class="text-h6 pl-2">
9
+ <v-skeleton-loader
10
+ v-if="rootStore.loading || $stores[type].loading"
11
+ type="heading"
12
+ />
13
+ <template v-else>
14
+ {{ item.firstname + " " + item.lastname }}
15
+ </template>
16
+ </v-col>
17
+ <v-col align-self="center">
18
+ <PeopleGroupBadges :item="item" />
19
+ </v-col>
20
+ </v-row>
21
+ </template>
22
+ <script setup>
23
+ import { useRootStore } from "../../stores/root"
24
+ const { $stores } = useNuxtApp()
25
+ const localePath = useLocalePath()
26
+ const rootStore = useRootStore()
27
+ const props = defineProps({
28
+ item: {
29
+ type: Object,
30
+ required: true,
31
+ },
32
+ index: {
33
+ type: Number,
34
+ required: true,
35
+ },
36
+ })
37
+ </script>
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div>
3
+ {{ item.name }}
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ const props = defineProps({
9
+ item: {
10
+ type: Object,
11
+ required: true,
12
+ },
13
+ })
14
+ </script>
15
+
16
+ <style></style>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <div>
3
+ <v-skeleton-loader
4
+ v-if="rootStore.loading || $stores.people.loading"
5
+ type="chip"
6
+ />
7
+
8
+ <template
9
+ v-for="(value, key, index) in item.groups"
10
+ v-else
11
+ :key="key + index"
12
+ >
13
+ <template v-if="value && key === 'vintage'">
14
+ <v-chip
15
+ v-for="(vintage, index2) in item.groups.vintage"
16
+ :key="index2"
17
+ class="mt-3 mr-3"
18
+ variant="outlined"
19
+ tile
20
+ style="background-color: white; color: black"
21
+ >
22
+ {{ $t("vintage", [vintage.year]) }}
23
+ </v-chip>
24
+ </template>
25
+
26
+ <v-chip
27
+ v-if="
28
+ value &&
29
+ ((!item.groups.vintage && key === 'vintage') ||
30
+ !['vintage', '__typename'].includes(key))
31
+ "
32
+ class="mt-3 mr-3"
33
+ color="black"
34
+ style="background-color: white; color: black"
35
+ tile
36
+ variant="outlined"
37
+ >
38
+ {{ $t("list.filters.people.groups." + key) }}</v-chip
39
+ ></template
40
+ >
41
+ </div>
42
+ </template>
43
+
44
+ <script setup>
45
+ import { useRootStore } from "../../stores/root"
46
+ const rootStore = useRootStore()
47
+ const { $stores } = useNuxtApp()
48
+ const props = defineProps({
49
+ item: {
50
+ type: Object,
51
+ required: true,
52
+ },
53
+ })
54
+ </script>
55
+
56
+ <style lang="scss" scoped></style>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <v-sheet
3
+ :to="
4
+ localePath({
5
+ name: 'people-slug',
6
+ params: { slug: slugify(item.firstname + item.lastname) }, //TODO à modifier
7
+ })
8
+ "
9
+ >
10
+ <v-row>
11
+ <v-col v-if="lgAndUp" cols="3">
12
+ <MiscAtomsImageContainer
13
+ cover
14
+ :loading="rootStore.loading"
15
+ :src="item.image"
16
+ :ratio="1 / 1"
17
+ :link="item.firstname + item.lastname"
18
+ :name="people - slug"
19
+ />
20
+ </v-col>
21
+ <v-col cols="12" lg="9">
22
+ <v-skeleton-loader v-if="rootStore.loading" type="heading" />
23
+ <template v-else>
24
+ <div class="text-h6">
25
+ {{ item.firstname + " " + item.lastname }}
26
+ </div>
27
+ </template>
28
+ </v-col></v-row
29
+ ></v-sheet
30
+ >
31
+ </template>
32
+
33
+ <script setup>
34
+ import { useDisplay } from "vuetify"
35
+ import { useRootStore } from "../../stores/root"
36
+ const localePath = useLocalePath()
37
+ const rootStore = useRootStore()
38
+ const { lgAndUp } = useDisplay()
39
+
40
+ const props = defineProps({ item: { type: Object, required: true } })
41
+ </script>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <v-divider v-if="index > 0" />
3
+ <v-row
4
+ class="my-6 ml-md-1 px-3 px-md-0 highlight-on-hover"
5
+ @click="
6
+ $router.push(
7
+ localePath({
8
+ name: 'people-slug',
9
+ params: { slug: item.slug },
10
+ })
11
+ )
12
+ "
13
+ >
14
+ <v-col v-if="mdAndUp" cols="12" md="3">
15
+ <MiscAtomsImageContainer
16
+ cover
17
+ :loading="$stores.people.loading"
18
+ :src="item.image.url ? item.image : '/default.png'"
19
+ :ratio="1 / 1"
20
+ :name="item.lastname + ' ' + item.firstname"
21
+ :slug="item.slug"
22
+ link="people-slug"
23
+ />
24
+ </v-col>
25
+
26
+ <v-col cols="12" md="8">
27
+ <v-skeleton-loader
28
+ v-if="$stores.people.loading"
29
+ :type="
30
+ [
31
+ 'heading, subtitle, text@5',
32
+ 'heading, subtitle, text@5',
33
+ 'heading, subtitle, text@3',
34
+ 'heading, subtitle, text@6',
35
+ 'heading, subtitle, text@9',
36
+ 'heading, subtitle, text@9',
37
+ ][['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')]
38
+ "
39
+ />
40
+
41
+ <div v-else class="ml-md-8">
42
+ <NuxtLink
43
+ :to="
44
+ localePath({
45
+ name: 'people-slug',
46
+ params: { slug: item.slug },
47
+ })
48
+ "
49
+ class="text-wrap text-h5 text-md-h4 text-black"
50
+ >
51
+ {{ item.firstname + " " + item.lastname }}
52
+ </NuxtLink>
53
+ <MiscAtomsSocials v-if="item.socials" :socials="item.socials" />
54
+ <PeopleGroupBadges :item="item" />
55
+
56
+ <MDC
57
+ v-if="item.biography"
58
+ :value="item.biography"
59
+ class="text-wrap clamped-text text-black"
60
+ :style="'-webkit-line-clamp:' + lineClamp"
61
+ />
62
+ </div>
63
+ </v-col>
64
+ </v-row>
65
+ </template>
66
+ <script setup>
67
+ import { useDisplay } from "vuetify"
68
+
69
+ const { name, mdAndUp } = useDisplay()
70
+ const localePath = useLocalePath()
71
+ const props = defineProps({
72
+ item: {
73
+ type: Object,
74
+ required: true,
75
+ },
76
+ index: {
77
+ type: Number,
78
+ required: true,
79
+ },
80
+ })
81
+ const lineClamp = computed(() => {
82
+ let base = [5, 6, 3, 6, 8, 10][
83
+ ["xs", "sm", "md", "lg", "xl", "xxl"].indexOf(name.value || "md")
84
+ ]
85
+ if (props.item?.socials && Object.keys(props.item.socials).length > 0) {
86
+ base =
87
+ base -
88
+ [0, 0, 1, 1, 1, 2][
89
+ ["xs", "sm", "md", "lg", "xl", "xxl"].indexOf(name.value || "md")
90
+ ]
91
+ }
92
+
93
+ return base
94
+ })
95
+ </script>
@@ -0,0 +1,162 @@
1
+ <template>
2
+ <v-row justify="center">
3
+ <v-col cols="12" sm="11" md="8" lg="8" xl="6">
4
+ <v-row no-gutters class="justify-center">
5
+ <v-col cols="12" sm="10" md="6" class="text-center">
6
+ <!-- PEOPLE IMAGE -->
7
+ <MiscAtomsImageContainer
8
+ v-if="mdAndUp && item && item.image"
9
+ cover
10
+ :loading="loading"
11
+ :src="item.image"
12
+ :ratio="1 / 1"
13
+ :width="
14
+ [200, 250, 250, 300][
15
+ ['md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
16
+ ]
17
+ "
18
+ />
19
+ </v-col>
20
+ <v-col cols="12" class="text-center">
21
+ <!-- FIRSTNAME LASTNAME -->
22
+ <v-skeleton-loader
23
+ v-if="loading"
24
+ class="mx-auto"
25
+ :max-width="
26
+ ['300', '400', '340', '400', '600', '600'][
27
+ ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
28
+ ]
29
+ "
30
+ :type="
31
+ [
32
+ 'heading@2, ossein, avatar@4, ossein, chip@3',
33
+ 'heading, ossein, avatar@6, ossein, chip@4',
34
+ 'heading, ossein, avatar@5, ossein, chip@3',
35
+ 'heading, ossein, avatar@6, ossein, chip@4',
36
+ 'heading, ossein, avatar@9, ossein, chip@6',
37
+ 'heading, ossein, avatar@9, ossein, chip@6',
38
+ ][['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')]
39
+ "
40
+ />
41
+
42
+ <template v-else>
43
+ <div
44
+ v-if="item && item.firstname && item.lastname"
45
+ class="my-8 text-h3 align-self-center text-wrap"
46
+ >
47
+ {{ item.firstname + " " + item.lastname
48
+ }}<!-- TODO : call a composable to format people names (multiple, initials, capped & al. )-->
49
+ </div>
50
+ <!-- SOCIALS -->
51
+ <div class="text-center">
52
+ <MiscAtomsSocials
53
+ v-if="item && item.socials"
54
+ :socials="item.socials"
55
+ />
56
+ </div>
57
+ <!-- GROUPS -->
58
+ <div class="mt-6 align-self-center">
59
+ <PeopleGroupBadges v-if="item && item.groups" :item="item" />
60
+ </div>
61
+ </template>
62
+ </v-col>
63
+ </v-row>
64
+
65
+ <!-- DIVIDERS -->
66
+ <v-responsive class="mx-auto my-6" width="120">
67
+ <v-divider class="mb-1" />
68
+ <v-divider />
69
+ </v-responsive>
70
+
71
+ <div class="text-overline mt-6">
72
+ <v-skeleton-loader v-if="loading" width="200" type="heading" />
73
+ <div v-else>
74
+ {{ $t("biography") }}
75
+ </div>
76
+ </div>
77
+
78
+ <v-skeleton-loader
79
+ v-if="loading"
80
+ :type="
81
+ ['text@16', 'text@16', 'text@16', 'text@12', 'text@12', 'text@12'][
82
+ ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
83
+ ]
84
+ "
85
+ />
86
+ <template v-else>
87
+ <MDC
88
+ v-if="item.biography"
89
+ :value="item.biography"
90
+ class="my-6 flex-wrap"
91
+ />
92
+ </template>
93
+
94
+ <!-- DIVIDERS -->
95
+ <v-responsive class="mx-auto my-9" width="120">
96
+ <v-divider class="mb-1" />
97
+ <v-divider />
98
+ </v-responsive>
99
+
100
+ <!-- POSITIONS AND AFFILIATIONS -->
101
+ <div class="text-overline mt-6">
102
+ <v-skeleton-loader v-if="loading" width="200" type="heading" />
103
+ <div v-else>
104
+ {{ $t("positions-and-affiliations") }}
105
+ </div>
106
+ </div>
107
+
108
+ <!-- BIOGRAPHY -->
109
+ <v-skeleton-loader v-if="loading" type="subtitle, text@2" width="300" />
110
+
111
+ <v-card
112
+ v-for="record in item.affiliations"
113
+ v-else-if="item && item.affiliations"
114
+ :key="record.affiliation"
115
+ flat
116
+ >
117
+ <v-card-item class="px-0">
118
+ <v-card-title class="text-wrap">
119
+ {{ record.affiliation.name }}
120
+ </v-card-title>
121
+ <div
122
+ v-for="(position, index) in record.positions"
123
+ :key="position.role + index"
124
+ class="text-body-2"
125
+ >
126
+ {{ position.role + " " + (position.department || "") }}
127
+ <span v-if="position.start" class="">
128
+ <!-- TODO FIx dates display -->
129
+ -
130
+ {{
131
+ $t("from {0} to {1}", [
132
+ formatDate(position.start, locale),
133
+ (position.stop && formatDate(position.stop, locale)) ||
134
+ $t("present"),
135
+ ])
136
+ }}
137
+ </span>
138
+ </div>
139
+ </v-card-item>
140
+ </v-card>
141
+ </v-col>
142
+ </v-row>
143
+
144
+ <!-- DIVIDERS -->
145
+ <v-responsive class="mx-auto my-9" width="120">
146
+ <v-divider class="mb-1" />
147
+ <v-divider />
148
+ </v-responsive>
149
+ <MiscMoleculesRelated v-if="item && item.related" :related="item.related" />
150
+ </template>
151
+
152
+ <script setup>
153
+ import { useDisplay } from "vuetify"
154
+ const { locale } = useI18n()
155
+ const { $stores } = useNuxtApp()
156
+ const { name, mdAndUp } = useDisplay()
157
+ const props = defineProps({
158
+ item: { type: Object, required: true },
159
+ loading: { type: Boolean, default: false },
160
+ })
161
+ $stores.people.loading = false
162
+ </script>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <div>{{ item.name }}</div>
3
+ </template>
4
+
5
+ <script lang="ts" setup>
6
+ const props = defineProps({
7
+ item: {
8
+ type: Object,
9
+ required: true,
10
+ },
11
+ })
12
+ </script>
13
+
14
+ <style></style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <v-sheet
3
+ :to="
4
+ localePath({
5
+ name: 'activities-projects-slug',
6
+ params: { slug: item.name },
7
+ })
8
+ "
9
+ >
10
+ <v-row>
11
+ <v-col v-if="lgAndUp" cols="3">
12
+ <MiscAtomsImageContainer
13
+ contain
14
+ :src="item.image"
15
+ :loading="rootStore.loading"
16
+ :ratio="1 / 1"
17
+ :link="item.name"
18
+ name="activities-projects-slug"
19
+ />
20
+ </v-col>
21
+ <v-col cols="12" lg="9">
22
+ <v-skeleton-loader v-if="rootStore.loading" type="heading, text@3" />
23
+ <template v-else>
24
+ <div class="text-h6">
25
+ {{ item.name }}
26
+ </div>
27
+ <div class="text-body-1">
28
+ {{ item.shortDescription }}
29
+ </div>
30
+ </template>
31
+ </v-col>
32
+ </v-row>
33
+ </v-sheet>
34
+ </template>
35
+
36
+ <script setup>
37
+ import { useDisplay } from "vuetify"
38
+ import { useRootStore } from "../../stores/root"
39
+ const localePath = useLocalePath()
40
+ const rootStore = useRootStore()
41
+ const { lgAndUp } = useDisplay()
42
+
43
+ const props = defineProps({ item: { type: Object, required: true } })
44
+ </script>
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <v-row class="highlight-on-hover pa-3">
3
+ <v-col v-ripple cols="12" sm="6" md="4" lg="3" xl="2">
4
+ <MiscAtomsImageContainer
5
+ contain
6
+ :src="item.image"
7
+ :loading="$stores.projects.loading"
8
+ :ratio="1 / 1"
9
+ :title="item.name"
10
+ link="activities-projects-slug"
11
+ :slug="item.slug[locale]"
12
+ />
13
+ </v-col>
14
+ <v-col
15
+ v-ripple
16
+ cols="12"
17
+ sm="6"
18
+ md="8"
19
+ lg="9"
20
+ xl="10"
21
+ class="px-6 cursor-pointer"
22
+ @click="
23
+ router.push(localePath('/activities/projects/' + item.slug[locale]))
24
+ "
25
+ >
26
+ <v-skeleton-loader
27
+ v-if="rootStore.loading"
28
+ type="heading,ossein,text@8,ossein,button,button"
29
+ />
30
+
31
+ <template v-else>
32
+ <div class="text-h5 text-sm-h3 text-md-h4 text-md-h4 my-6">
33
+ {{ item.name }}
34
+ </div>
35
+
36
+ <MDC
37
+ v-if="item.summary"
38
+ class="mt-n3 text-wrap clamped-text"
39
+ :style="
40
+ '-webkit-line-clamp:' +
41
+ [5, 5, 4, 8, 10][
42
+ ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
43
+ ]
44
+ "
45
+ :value="item.summary"
46
+ />
47
+
48
+ <v-btn
49
+ class="mt-4"
50
+ variant="outlined"
51
+ tile
52
+ :to="
53
+ localePath({
54
+ name: 'project-slug',
55
+ params: { slug: item.slug[locale] },
56
+ })
57
+ "
58
+ :size="
59
+ ['small', 'small', 'small', 'default', 'default', 'large'][
60
+ ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
61
+ ]
62
+ "
63
+ >
64
+ {{ $t("read-more") }}
65
+ </v-btn>
66
+ <v-btn
67
+ variant="outlined"
68
+ tile
69
+ class="mt-4 ml-4"
70
+ prepend-icon="mdi-web"
71
+ :size="
72
+ ['small', 'small', 'small', 'default', 'default', 'large'][
73
+ ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
74
+ ]
75
+ "
76
+ >{{ $t("visit-the-project-website") }}</v-btn
77
+ >
78
+ </template>
79
+ </v-col></v-row
80
+ >
81
+ <v-divider />
82
+ </template>
83
+
84
+ <script setup>
85
+ import { useRootStore } from "../../stores/root"
86
+ import { useDisplay } from "vuetify"
87
+ const { locale } = useI18n()
88
+
89
+ const { name } = useDisplay()
90
+
91
+ const rootStore = useRootStore()
92
+ const router = useRouter()
93
+ const localePath = useLocalePath()
94
+
95
+ const props = defineProps({
96
+ item: {
97
+ type: Object,
98
+ default: () => {
99
+ return {}
100
+ },
101
+ required: true,
102
+ },
103
+ })
104
+ </script>
105
+
106
+ <style lang="scss"></style>