1+ <template >
2+ <v-container >
3+ <div class =" prose" id =" contentDiv" >
4+ <ContentRenderer :value =" data" v-if =" data" :key =" data._path" >
5+ <p class =" text-h2 dividerline mt-4 mb-8" style =" color : #0080bc " >
6+ {{ data.title }}
7+ </p >
8+
9+ <ContentRendererMarkdown :value =" data.body" />
10+ <div class =" text-center" >
11+ <v-btn
12+ color =" success"
13+ size =" x-large"
14+ @click =" changePath(stepsInfo[0].parentPath)"
15+ prepend-icon =" mdi-play"
16+ >
17+ Start now !
18+ </v-btn >
19+ </div >
20+
21+ <p class =" text-h4" >Program</p >
22+ <v-timeline side =" end" truncate-line =" both" >
23+ <v-timeline-item
24+ v-for =" (c, kc) in stepsInfo"
25+ :key =" kc"
26+ :dot-color =" c.color"
27+ size =" small"
28+ >
29+ <CardSession :itemSession =" c" />
30+ </v-timeline-item >
31+ </v-timeline >
32+ </ContentRenderer >
33+ </div >
34+ <br />
35+ <div class =" text-center" >
36+ <v-btn
37+ color =" success"
38+ size =" x-large"
39+ @click =" changePath(stepsInfo[0].parentPath)"
40+ prepend-icon =" mdi-play"
41+ >
42+ Start now !
43+ </v-btn >
44+ </div >
45+ </v-container >
46+ </template >
47+
48+ <script >
49+ import " /node_modules/flag-icons/css/flag-icons.min.css" ;
50+ import { useStorage } from " @vueuse/core" ;
51+
52+ export default {
53+ data () {
54+ return {
55+ data: " " ,
56+ path: null ,
57+ };
58+ },
59+ async setup () {
60+ // Manage path and get language
61+ const route = useRoute ();
62+ let lang = route .params .lang ;
63+ const id = ref (route .query .id ? route .query .id : " " );
64+ var step = ref (route .query .step ? route .query .step : 0 );
65+ const pathParent = route .path ;
66+ const path = route .path + id .value ;
67+
68+ // Get Tuto pages
69+ const tutosList = await queryContent (path).find ();
70+ var steps = null ;
71+
72+ for (var i = tutosList .length - 1 ; i >= 0 ; i-- ) {
73+ if (
74+ tutosList[i]._path == path + " _dir" ||
75+ tutosList[i]._path == path + " /_dir"
76+ ) {
77+ steps = tutosList[i];
78+ tutosList .splice (i, 1 );
79+ }
80+ }
81+
82+ const theDefault = {};
83+ const state = useStorage (" my-progression-store" , theDefault, localStorage, {
84+ mergeDefaults: true ,
85+ });
86+ state .value [path] = { status: " started" , step: 0 };
87+
88+ var stepsInfo = [];
89+ for (const i in steps .navigation .steps ) {
90+ var tempPath;
91+ if (steps .navigation .steps [i].indexOf (" /" ) === 0 ) {
92+ tempPath = steps .navigation .steps [i];
93+ } else {
94+ tempPath = " /" + steps .navigation .steps [i];
95+ }
96+ const temp = await queryContent (tempPath + " /_dir" ).findOne ();
97+
98+ temp[" parentPath" ] = steps .navigation .steps [i];
99+ temp[" type" ] = steps .navigation .steps [i].split (" /" )[0 ];
100+
101+ if (tempPath in state .value ) {
102+ if (state .value [tempPath].status == " started" ) {
103+ temp[" color" ] = " blue" ;
104+ } else {
105+ temp[" color" ] = " green" ;
106+ }
107+ } else {
108+ temp[" color" ] = " grey" ;
109+ }
110+ stepsInfo .push (temp);
111+ }
112+
113+ return {
114+ tutosList,
115+ steps,
116+ stepsInfo,
117+ pathParent,
118+ id,
119+ step,
120+ lang,
121+ state,
122+ };
123+ },
124+ async mounted () {
125+ this .data = this .tutosList [this .step ];
126+ },
127+ methods: {
128+ changePath (stepPath ) {
129+ var pathParts = stepPath .replace (" /_dir" , " " );
130+ var id = pathParts .split (" /" );
131+ id = id[id .length - 1 ];
132+ const router = useRouter ();
133+ if (! pathParts .startsWith (' /' )){
134+ pathParts = " /" + pathParts
135+ }
136+
137+ router .push ({
138+ path: pathParts .replace (id, " " ),
139+ query: { id: id },
140+ });
141+ },
142+ },
143+ };
144+ </script >
145+
146+ <style >
147+ .gutter {
148+ background-color : #eee ;
149+ background-repeat : no-repeat ;
150+ background-position : 50% ;
151+ }
152+
153+ .gutter.gutter-vertical {
154+ background-image : url (" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=" );
155+ cursor : row-resize ;
156+ }
157+
158+ p {
159+ margin-top : 10px ;
160+ margin-bottom : 10px ;
161+ }
162+
163+ div .prose pre {
164+ border : solid gray 1px ;
165+ padding : 5px ;
166+ }
167+
168+ div .prose a {
169+ color : black ;
170+ text-decoration : none ;
171+ }
172+
173+ pre {
174+ overflow-x : auto !important ;
175+ margin-bottom : 10px !important ;
176+ }
177+ li {
178+ margin-left : 25px ;
179+ }
180+ .math {
181+ font-family : Courier , monospace ;
182+ }
183+ </style >
0 commit comments