3
3
<HeroSection />
4
4
<Roadmap />
5
5
<Teleport to =" body" >
6
- <div v-if =" content" :class =" ['fixed top-0 h-screen', sidebarClass]" >
7
- <div
8
- class =" prose dark:prose-invert max-w-full flex overflow-y-auto overflow-x-hidden h-full w-full flex-col items-center p-4 focus:outline-0 sm:p-6 bg-orange-50 dark:bg-gray-800"
9
- >
10
- <div class =" w-full flex flex-row justify-between px-4 pb-2" >
11
- <Dropdown
12
- ref =" statusDropDown"
13
- :customTriggerClass =" ['px-4 py-2 border-black border', status.toLowerCase()]"
14
- :border =" false"
6
+ <div v-if =" content" :class =" ['fixed top-0 h-screen', sidebarClass]" >
7
+ <div
8
+ id =" sidebar"
9
+ class =" scroll-smooth prose dark:prose-invert max-w-full flex overflow-y-auto overflow-x-hidden h-full w-full flex-col items-center p-4 focus:outline-0 sm:p-6 bg-orange-50 dark:bg-gray-800"
10
+ @scroll =" onScroll"
11
+ >
12
+ <div
13
+ :class =" [
14
+ 'sticky border-b -top-6 bg-orange-50 dark:bg-gray-800 w-full flex flex-row items-center justify-between px-4',
15
+ !isScrolled
16
+ ? '!border-transparent pb-2'
17
+ : 'border-gray-300 dark:border-gray-700 mb-2 py-2',
18
+ ]"
15
19
>
16
- <!-- trigger element -->
17
- <template #trigger >
18
- <button type =" button" v-text =" status" />
19
- </template >
20
+ <Dropdown
21
+ ref =" statusDropDown"
22
+ :customTriggerClass =" [
23
+ 'px-3 py-1 hover:bg-orange-100 dark:hover:bg-gray-700 dark:border-gray-700 border',
24
+ status.toLowerCase(),
25
+ ]"
26
+ :border =" false"
27
+ >
28
+ <!-- trigger element -->
29
+ <template #trigger >
30
+ <button type =" button" v-text =" status" />
31
+ </template >
20
32
21
- <!-- contents display in dropdown -->
22
- <ul class =" flex flex-col bg-orange-100 dark:bg-gray-600" >
23
- <li
24
- v-for =" (s, i) in allStatus"
25
- :key =" 'status-' + i"
26
- @click =" changeStatus(s)"
27
- :class =" ['px-4 py-2 hover:cursor-pointer border-b border-black hover:bg-orange-50 dark:hover:bg-gray-500', s.toLowerCase()]"
28
- v-text =" s"
33
+ <!-- contents display in dropdown -->
34
+ <ul class =" flex flex-col bg-orange-100 dark:bg-gray-600" >
35
+ <li
36
+ v-for =" (s, i) in allStatus"
37
+ :key =" 'status-' + i"
38
+ @click =" changeStatus(s)"
39
+ :class =" [
40
+ 'px-4 py-2 hover:cursor-pointer border-b border-orange-200 dark:border-gray-500 hover:bg-orange-50 dark:hover:bg-gray-500',
41
+ s.toLowerCase(),
42
+ ]"
43
+ v-text =" s"
44
+ ></li >
45
+ </ul >
46
+ </Dropdown >
47
+ <span
48
+ class =" hover:cursor-pointer dark:text-white"
49
+ @click =" closeSidebar"
50
+ >
51
+ <svg
52
+ xmlns =" http://www.w3.org/2000/svg"
53
+ width =" 16"
54
+ height =" 16"
55
+ fill =" currentColor"
56
+ viewBox =" 0 0 256 256"
29
57
>
30
- </li >
31
- </ul >
32
- </Dropdown >
33
- <span class =" hover:cursor-pointer" @click =" closeSidebar" >X</span >
34
- </div >
35
- <ContentRenderer :key =" content._id" :value =" content" >
36
- <ContentRendererMarkdown class =" flex flex-col w-full m:max-w-[800px] sm:max-w-[600px]" tag =" article" :value =" content" />
37
- <div class =" flex flex-col items-start w-full m:max-w-[800px] sm:max-w-[600px]" >
38
- <h4 id =" related-content" class =" mb-3" >
39
- <a href =" #related-content" >Contenido Extra Relacionado</a >
40
- </h4 >
41
- <a
42
- class =" gap-x-2 mb-1"
43
- v-for =" (link, i) in content.data.externalLinks.sort((a, b) => a.english - b.english)"
44
- :key =" i"
45
- :href =" link.link"
58
+ <path
59
+ d =" M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"
60
+ ></path >
61
+ </svg >
62
+ </span >
63
+ </div >
64
+ <ContentRenderer :key =" content._id" :value =" content" >
65
+ <ContentRendererMarkdown
66
+ class =" flex flex-col w-full m:max-w-[800px] sm:max-w-[600px]"
67
+ tag =" article"
68
+ :value =" content"
69
+ />
70
+ <div
71
+ class =" flex flex-col items-start w-full m:max-w-[800px] sm:max-w-[600px]"
72
+ >
73
+ <h4 id =" related-content" class =" mb-3" >
74
+ <a href =" #related-content" >Contenido Extra Relacionado</a >
75
+ </h4 >
76
+ <a
77
+ class =" gap-x-2 mb-1 no-underline"
78
+ v-for =" (link, i) in content.data.externalLinks.sort(
79
+ (a, b) => a.english - b.english
80
+ )"
81
+ :key =" i"
82
+ :href =" link.link"
83
+ target =" _blank"
46
84
>
47
- <Card moreTransparency >
85
+ <Card
86
+ moreTransparency
87
+ class =" border-gray-300 hover:text-gray-100 transition-colors dark:border-gray-700 dark:hover:bg-gray-600 dark:bg-transparent"
88
+ >
48
89
<strong v-if =" link.english" >[Contenido en Ingles]</strong >
49
- {{link.name}}
90
+ {{ link.name }}
50
91
</Card >
51
- </a >
52
- </div >
53
- </ContentRenderer >
92
+ </a >
93
+ </div >
94
+ </ContentRenderer >
95
+ </div >
54
96
</div >
55
- </div >
56
97
</Teleport >
57
98
</template >
58
99
59
100
<script setup lang="ts">
60
- import { useRoute } from ' vue-router'
61
- import { ref , onMounted } from ' vue'
62
- import Roadmap from ' @/components/Roadmap.vue'
63
- import HeroSection from ' @/layouts/hero.vue'
64
- import Dropdown from ' v-dropdown'
101
+ import { useRoute , useRouter } from " vue-router" ;
102
+ import { ref , onMounted } from " vue" ;
103
+ import Roadmap from " @/components/Roadmap.vue" ;
104
+ import HeroSection from " @/layouts/hero.vue" ;
105
+ import Dropdown from " v-dropdown" ;
65
106
66
- const { $locally } = useNuxtApp ()
67
-
68
- const allStatus = [ ' Pendiente' , ' Leyendo' , ' Completado' , ' Omitir' ]
69
- const route = useRoute ()
70
- const nodeId = route .params .slug
71
- const showSidebar = ref (true )
72
- const content = ref (null )
73
- const statusDropDown = ref (null )
74
- const status = ref ($locally .get (nodeId ) ?? ' Pendiente' )
107
+ const { $locally } = useNuxtApp ();
75
108
109
+ const allStatus = [" Pendiente" , " Leyendo" , " Completado" , " Omitir" ];
110
+ const { push } = useRouter ();
111
+ const route = useRoute ();
112
+ const nodeId = route .params .slug ;
113
+ const showSidebar = ref (true );
114
+ const content = ref (null );
115
+ const statusDropDown = ref (null );
116
+ const status = ref ($locally .get (nodeId ) ?? " Pendiente" );
117
+ const isScrolled = ref (false );
76
118
77
119
onMounted (async () => {
78
- if (! nodeId ) return
79
- const contentResult = await queryContent (nodeId .join (" /" )).findOne ()
80
- content .value = contentResult
81
- showSidebar .value = contentResult && (route .query .fromClick || false )
82
- })
120
+ if (! nodeId ) return ;
121
+ const contentResult = await queryContent (nodeId .join (" /" )).findOne ();
122
+ content .value = contentResult ;
123
+ showSidebar .value = contentResult && (route .query .fromClick || false );
124
+ });
83
125
84
126
const closeSidebar = () => {
85
127
content .value = null ;
86
- document .body .classList .remove (' overflow-hidden' )
87
- }
88
- const sidebarClass = computed (() => showSidebar .value ? ' right-0 w-screen lg:w-2/4' : ' w-screen' )
128
+ document .body .classList .remove (" overflow-hidden" );
129
+ push ({ path: " /" });
130
+ };
131
+ const onScroll = (e ) => {
132
+ const { scrollTop, offsetHeight, scrollHeight } = e .target ;
133
+ if (scrollTop !== 0 ) {
134
+ isScrolled .value = true ;
135
+ } else {
136
+ isScrolled .value = false ;
137
+ }
138
+ };
139
+ const sidebarClass = computed (() =>
140
+ showSidebar .value ? " right-0 w-screen lg:w-2/4" : " w-screen"
141
+ );
89
142
90
143
function changeStatus(val ) {
91
- if (val == status .value ) return
92
- if (! statusDropDown .value ) return
93
- status .value = val
94
- $locally .set (nodeId , val )
95
- statusDropDown .value .close ()
144
+ if (val == status .value ) return ;
145
+ if (! statusDropDown .value ) return ;
146
+ status .value = val ;
147
+ $locally .set (nodeId , val );
148
+ statusDropDown .value .close ();
96
149
}
97
150
</script >
98
151
@@ -101,14 +154,26 @@ function changeStatus(val) {
101
154
.leyendo ::before ,
102
155
.completado ::before ,
103
156
.omitir ::before {
104
- content : ' • ' ;
157
+ content : " • " ;
105
158
margin-right : 5px ;
106
159
}
107
160
108
- .pendiente ::before { color : var (--tw-text-gray-950 ); }
109
- .leyendo ::before { color : var (--tw-text-orange-500 ); }
110
- .completado ::before { color : var (--tw-text-green-600 ); }
111
- .omitir ::before { color : var (--tw-text-slate-500 ); }
112
-
113
- .v-dropdown-container.v-dropdown-no-border { border-radius : 0px !important }
161
+ .pendiente ::before {
162
+ color : var (--tw-text-gray-950 );
163
+ }
164
+ .leyendo ::before {
165
+ color : var (--tw-text-orange-500 );
166
+ }
167
+ .completado ::before {
168
+ color : var (--tw-text-green-600 );
169
+ }
170
+ .omitir ::before {
171
+ color : var (--tw-text-slate-500 );
172
+ }
173
+ article [id ] {
174
+ scroll-margin-top : 3.5rem ;
175
+ }
176
+ .v-dropdown-container.v-dropdown-no-border {
177
+ border-radius : 0px !important ;
178
+ }
114
179
</style >
0 commit comments