Browse Source

Add analysis data in flatdetails

Phyks (Lucas Verney) 3 years ago
parent
commit
9005ac02a6

+ 32
- 0
src/components/FlatDetails.vue View File

@@ -62,6 +62,17 @@
62 62
                             <DetailsTable :details="flat.details"></DetailsTable>
63 63
                         </v-flex>
64 64
                     </v-layout>
65
+
66
+                    <v-layout row align-center>
67
+                        <v-flex xs12>
68
+                            <h3 class="title">{{ $t('flatDetails.Analysis') }}</h3>
69
+                        </v-flex>
70
+                    </v-layout>
71
+                    <v-layout row align-center>
72
+                        <v-flex xs8 offset-xs2>
73
+                            <DetailsTable :details="analysis" :defaultValue="capitalize($t('misc.unknown'))"></DetailsTable>
74
+                        </v-flex>
75
+                    </v-layout>
65 76
                 </template>
66 77
                 <template v-else>
67 78
                     <p>{{ $t('flatDetails.notFound') }}</p>
@@ -72,6 +83,11 @@
72 83
 </template>
73 84
 
74 85
 <script>
86
+import currencyFormatter from 'currency-formatter';
87
+
88
+import { capitalize } from '@/tools';
89
+import { formatAreaUnits } from '@/tools/units';
90
+
75 91
 import DetailsTable from '@/components/ui/DetailsTable.vue';
76 92
 import FormattedArea from '@/components/ui/FormattedArea.vue';
77 93
 import FormattedBedrooms from '@/components/ui/FormattedBedrooms.vue';
@@ -110,6 +126,7 @@ export default {
110 126
                 this.isLoading = false;
111 127
             });
112 128
         },
129
+        capitalize,
113 130
     },
114 131
     computed: {
115 132
         flat() {
@@ -118,6 +135,21 @@ export default {
118 135
         flatIsNotEmpty() {
119 136
             return Object.keys(this.flat).length !== 0;
120 137
         },
138
+        analysis() {
139
+            const analysisResults = {};
140
+
141
+            const postalCode = this.flat.flatisfy_postal_code;
142
+            analysisResults[this.$t('flatDetails.postalCode')] = `${postalCode.name} (${postalCode.postal_code})`;
143
+
144
+            analysisResults[this.$t('flatDetails.nearbyStations')] = this.flat.flatisfy_stations.join(', ');
145
+            analysisResults[this.$t('flatDetails.travelTimes')] = this.flat.flatisfy_time_to;
146
+
147
+            const costPerArea = Math.round(this.flat.cost / this.flat.area);
148
+            const formattedAreaUnits = formatAreaUnits(this.flat.areaUnits);
149
+            analysisResults[this.$t('flatDetails.costPerArea', { unit: formattedAreaUnits })] = currencyFormatter.format(costPerArea, { code: this.flat.currency, precision: 0 });
150
+
151
+            return analysisResults;
152
+        },
121 153
     },
122 154
 };
123 155
 </script>

+ 84
- 55
src/components/onboarding/Configuration.vue View File

@@ -10,31 +10,32 @@
10 10
             <v-container class="panel">
11 11
                 <v-layout row wrap class="text-xs-center">
12 12
                     <v-flex xs12 v-if="currentStep === 1">
13
-                        <v-layout row >
14
-                            <v-flex xs12>
15
-                                <v-select v-bind:items="TYPES" :label="$t('configuration.Iwantto')"></v-select>
16
-                            </v-flex>
17
-                        </v-layout>
18
-                        <v-layout row>
19
-                            <v-flex xs12>
20
-                                <p>Une maison / un appart / un parking</p>
21
-                            </v-flex>
22
-                        </v-layout>
23
-                        <v-layout row>
24
-                            <v-flex xs12>
25
-                                <h2>Où ?</h2>
26
-                            </v-flex>
27
-                        </v-layout>
28
-                        <v-layout row>
29
-                            <v-flex xs12>
30
-                                <v-select
31
-                                    v-bind:items="postalCodes"
32
-                                    :label="$t('configuration.postalCodes')"
33
-                                    autocomplete
34
-                                    multiple
35
-                                    ></v-select>
36
-                            </v-flex>
37
-                        </v-layout>
13
+                        <template v-if="isLoading">
14
+                            <v-progress-circular indeterminate color="primary"></v-progress-circular>
15
+                        </template>
16
+                        <template v-else>
17
+                            <v-layout row >
18
+                                <v-flex xs12>
19
+                                    <v-select v-bind:items="TYPES" :label="$t('configuration.Iwantto')" required></v-select>
20
+                                </v-flex>
21
+                            </v-layout>
22
+                            <v-layout row>
23
+                                <v-flex xs12>
24
+                                    <p>Une maison / un appart / un parking</p>
25
+                                </v-flex>
26
+                            </v-layout>
27
+                            <v-layout row>
28
+                                <v-flex xs12>
29
+                                    <v-select
30
+                                        v-bind:items="postalCodes"
31
+                                        :label="$t('configuration.in')"
32
+                                        autocomplete
33
+                                        multiple
34
+                                        required
35
+                                        ></v-select>
36
+                                </v-flex>
37
+                            </v-layout>
38
+                        </template>
38 39
                     </v-flex>
39 40
 
40 41
                     <v-flex xs12 v-else-if="currentStep === 2">
@@ -49,17 +50,17 @@
49 50
                                 <v-card>
50 51
                                     <v-card-text class="grey lighten-3">
51 52
                                         <v-layout row>
52
-                                            <v-flex xs3>
53
-                                                <v-subheader>{{ $t('configuration.Between') }}</v-subheader>
53
+                                            <v-flex xs2 offset-xs1>
54
+                                                <v-subheader class="subheader"><span>{{ $t('configuration.Between') }}</span></v-subheader>
54 55
                                             </v-flex>
55
-                                            <v-flex xs3>
56
-                                                <v-text-field type="number" suffix="€"></v-text-field>
56
+                                            <v-flex xs2>
57
+                                                <v-text-field type="number" :suffix="currency"></v-text-field>
57 58
                                             </v-flex>
58
-                                            <v-flex xs3>
59
-                                                <v-subheader>{{ $t('configuration.and') }}</v-subheader>
59
+                                            <v-flex xs2>
60
+                                                <v-subheader class="subheader"><span>{{ $t('configuration.and') }}</span></v-subheader>
60 61
                                             </v-flex>
61
-                                            <v-flex xs3>
62
-                                                <v-text-field type="number" suffix="€"></v-text-field>
62
+                                            <v-flex xs2>
63
+                                                <v-text-field type="number" :suffix="currency"></v-text-field>
63 64
                                             </v-flex>
64 65
                                         </v-layout>
65 66
                                     </v-card-text>
@@ -70,60 +71,66 @@
70 71
                                 <v-card>
71 72
                                     <v-card-text class="grey lighten-3">
72 73
                                         <v-layout row>
73
-                                            <v-flex xs3>
74
-                                                <v-subheader>{{ $t('configuration.Between') }}</v-subheader>
74
+                                            <v-flex xs2 offset-xs1>
75
+                                                <v-subheader><span>{{ $t('configuration.Between') }}</span></v-subheader>
75 76
                                             </v-flex>
76
-                                            <v-flex xs3>
77
-                                                <v-text-field type="number" suffix="m<sup>2</sup>"></v-text-field>
77
+                                            <v-flex xs2>
78
+                                                <v-text-field type="number" :suffix="formattedAreaUnits"></v-text-field>
78 79
                                             </v-flex>
79
-                                            <v-flex xs3>
80
-                                                <v-subheader>{{ $t('configuration.and') }}</v-subheader>
80
+                                            <v-flex xs2>
81
+                                                <v-subheader><span>{{ $t('configuration.and') }}</span></v-subheader>
81 82
                                             </v-flex>
82
-                                            <v-flex xs3>
83
-                                                <v-text-field type="number" suffix="m<sup>2</sup>"></v-text-field>
83
+                                            <v-flex xs2>
84
+                                                <v-text-field type="number" :suffix="formattedAreaUnits"></v-text-field>
84 85
                                             </v-flex>
85 86
                                         </v-layout>
86 87
                                     </v-card-text>
87 88
                                 </v-card>
88 89
                             </v-expansion-panel-content>
89 90
                             <v-expansion-panel-content>
90
-                                <div slot="header">{{ $t('configuration.Rooms') }}</div>
91
+                                <div slot="header">{{ capitalize($t('configuration.rooms')) }}</div>
91 92
                                 <v-card>
92 93
                                     <v-card-text class="grey lighten-3">
93 94
                                         <v-layout row>
94
-                                            <v-flex xs3>
95
-                                                <v-subheader>{{ $t('configuration.Between') }}</v-subheader>
95
+                                            <v-flex xs2 offset-xs1>
96
+                                                <v-subheader><span>{{ $t('configuration.Between') }}</span></v-subheader>
96 97
                                             </v-flex>
97
-                                            <v-flex xs3>
98
+                                            <v-flex xs2>
98 99
                                                 <v-text-field type="number"></v-text-field>
99 100
                                             </v-flex>
100
-                                            <v-flex xs3>
101
-                                                <v-subheader>{{ $t('configuration.and') }}</v-subheader>
101
+                                            <v-flex xs2>
102
+                                                <v-subheader><span>{{ $t('configuration.and') }}</span></v-subheader>
102 103
                                             </v-flex>
103
-                                            <v-flex xs3>
104
+                                            <v-flex xs2>
104 105
                                                 <v-text-field type="number"></v-text-field>
105 106
                                             </v-flex>
107
+                                            <v-flex xs2>
108
+                                                <v-subheader><span>{{ $t('configuration.rooms') }}</span></v-subheader>
109
+                                            </v-flex>
106 110
                                         </v-layout>
107 111
                                     </v-card-text>
108 112
                                 </v-card>
109 113
                             </v-expansion-panel-content>
110 114
                             <v-expansion-panel-content>
111
-                                <div slot="header">{{ $t('configuration.Bedrooms') }}</div>
115
+                                <div slot="header">{{ capitalize($t('configuration.bedrooms')) }}</div>
112 116
                                 <v-card>
113 117
                                     <v-card-text class="grey lighten-3">
114 118
                                         <v-layout row>
115
-                                            <v-flex xs3>
116
-                                                <v-subheader>{{ $t('configuration.Between') }}</v-subheader>
119
+                                            <v-flex xs2 offset-xs1>
120
+                                                <v-subheader><span>{{ $t('configuration.Between') }}</span></v-subheader>
117 121
                                             </v-flex>
118
-                                            <v-flex xs3>
122
+                                            <v-flex xs2>
119 123
                                                 <v-text-field type="number"></v-text-field>
120 124
                                             </v-flex>
121
-                                            <v-flex xs3>
122
-                                                <v-subheader>{{ $t('configuration.and') }}</v-subheader>
125
+                                            <v-flex xs2>
126
+                                                <v-subheader><span>{{ $t('configuration.and') }}</span></v-subheader>
123 127
                                             </v-flex>
124
-                                            <v-flex xs3>
128
+                                            <v-flex xs2>
125 129
                                                 <v-text-field type="number"></v-text-field>
126 130
                                             </v-flex>
131
+                                            <v-flex xs2>
132
+                                                <v-subheader><span>{{ $t('configuration.bedrooms') }}</span></v-subheader>
133
+                                            </v-flex>
127 134
                                         </v-layout>
128 135
                                     </v-card-text>
129 136
                                 </v-card>
@@ -153,14 +160,20 @@
153 160
 
154 161
 <script>
155 162
 import * as api from '@/api';
163
+import { capitalize } from '@/tools';
164
+import { formatAreaUnits } from '@/tools/units';
156 165
 
157 166
 export default {
167
+    // TODO: Validation
158 168
     data() {
159 169
         return {
160 170
             TYPES: [this.$t('configuration.buy'), this.$t('configuration.rent')],
161 171
             MAX_STEPS: 3,
162 172
             rawPostalCodes: [],
173
+            isLoading: false,
163 174
             error: null,  // TODO
175
+            currency: '€',
176
+            areaUnits: 'm^2',
164 177
         };
165 178
     },
166 179
     created() {
@@ -199,6 +212,9 @@ export default {
199 212
         postalCodes() {
200 213
             return this.rawPostalCodes.map(x => `${x.postal_code} - ${x.name}`);
201 214
         },
215
+        formattedAreaUnits() {
216
+            return formatAreaUnits(this.areaUnits);
217
+        },
202 218
     },
203 219
     methods: {
204 220
         checkStep() {
@@ -209,10 +225,13 @@ export default {
209 225
             }
210 226
         },
211 227
         fetchData() {
228
+            this.isLoading = true;
212 229
             return api.getPostalCodes().then((postalCodes) => {
213 230
                 this.rawPostalCodes = postalCodes;
231
+                this.isLoading = false;
214 232
             });
215 233
         },
234
+        capitalize,
216 235
     },
217 236
 };
218 237
 </script>
@@ -222,4 +241,14 @@ export default {
222 241
     position: absolute;
223 242
     bottom: 0;
224 243
 }
244
+
245
+.subheader {
246
+    font-size: 16px;
247
+    padding-top: 18px;
248
+}
249
+
250
+.subheader > span {
251
+    display: inline-block;
252
+    margin: auto;
253
+}
225 254
 </style>

+ 10
- 1
src/components/ui/DetailsTable.vue View File

@@ -8,7 +8,12 @@
8 8
                         {{ details[key] }}
9 9
                     </template>
10 10
                     <template v-else>
11
-                        <v-icon>check</v-icon>
11
+                        <template v-if="defaultValue">
12
+                            {{ defaultValue }}
13
+                        </template>
14
+                        <template v-else>
15
+                            <v-icon>check</v-icon>
16
+                        </template>
12 17
                     </template>
13 18
                 </td>
14 19
             </tr>
@@ -22,6 +27,10 @@ import { capitalize } from '@/tools';
22 27
 export default {
23 28
     props: {
24 29
         details: Object,
30
+        defaultValue: {
31
+            type: String,
32
+            default: null,
33
+        },
25 34
     },
26 35
     computed: {
27 36
         sortedDetailsKeys() {

+ 5
- 2
src/components/ui/FormattedArea.vue View File

@@ -5,6 +5,8 @@
5 5
 </template>
6 6
 
7 7
 <script>
8
+import { formatAreaUnits } from '@/tools/units';
9
+
8 10
 export default {
9 11
     props: {
10 12
         area: Number,
@@ -16,8 +18,9 @@ export default {
16 18
     },
17 19
     computed: {
18 20
         formattedArea() {
19
-            if (this.areaUnits === 'm^2') {
20
-                return `${this.area}&nbsp;m<sup>2</sup>`;
21
+            const formattedUnit = formatAreaUnits(this.areaUnits);
22
+            if (formattedUnit) {
23
+                return `${this.area}&nbsp;${formattedUnit}`;
21 24
             }
22 25
             return this.area;
23 26
         },

+ 11
- 3
src/i18n/index.js View File

@@ -11,6 +11,11 @@ const messages = {
11 11
             notFound: 'Annonce introuvable',
12 12
             Description: 'Description',
13 13
             Details: 'Détails',
14
+            Analysis: 'Analyse',
15
+            postalCode: 'Code postal',
16
+            nearbyStations: 'Transports publics',
17
+            travelTimes: 'Temps de trajet',
18
+            costPerArea: 'Prix au {unit}',
14 19
         },
15 20
         menu: {
16 21
             newFlats: 'Nouveautés',
@@ -33,10 +38,13 @@ const messages = {
33 38
             Price: 'Prix',
34 39
             Between: 'Entre',
35 40
             and: 'et',
36
-            Rooms: 'Pièces',
41
+            rooms: 'pièces',
37 42
             Area: 'Surface',
38
-            Bedrooms: 'Chambres',
39
-            postalCodes: 'Codes postaux',
43
+            bedrooms: 'chambres',
44
+            in: 'à',
45
+        },
46
+        misc: {
47
+            unknown: 'inconnu',
40 48
         },
41 49
     },
42 50
 };

+ 10
- 0
src/tools/units.js View File

@@ -0,0 +1,10 @@
1
+function formatAreaUnits(areaUnits) {
2
+    if (areaUnits === 'm^2') {
3
+        return 'm²';
4
+    }
5
+    return '';
6
+}
7
+
8
+export {
9
+    formatAreaUnits,
10
+};