|
1 | 1 | <script lang="ts"> |
2 | 2 | import { onMount, onDestroy, createEventDispatcher } from 'svelte' |
| 3 | + import { Toggle } from 'flowbite-svelte' |
3 | 4 | import { Modal } from 'flowbite' |
4 | 5 | import { _ } from 'svelte-i18n' |
5 | 6 | import SvgIcon from '../SvgIcon.svelte' |
6 | 7 | import { EXCHANGE_RATE_API_KEY, BITCOIN_API_KEY } from './../../helper/constant' |
7 | 8 | import { fetchExchangeRates } from './../../helper/utils' |
| 9 | + import { hashPassword } from './../../helper/auth' |
| 10 | + import { setPassword } from './../../helper/apis' |
| 11 | + import { alert, isPasswordAllowed } from './../../stores' |
8 | 12 | import type { ModalOptions } from 'flowbite' |
9 | 13 |
|
10 | 14 | const dispatch = createEventDispatcher() |
11 | | - const MODAL_KEY = 'setting-modal' |
12 | | - let modal = null |
13 | | - let loading = false |
14 | | - let error = '' |
15 | | - let rateApiKey = localStorage.getItem(EXCHANGE_RATE_API_KEY) || '' |
16 | | - let bitcoinApiKey = localStorage.getItem(BITCOIN_API_KEY) || '' |
| 15 | + let modal: any = null |
| 16 | + const MODAL_KEY: string = 'setting-modal' |
| 17 | + let loading: boolean = false |
| 18 | + let error: string = '' |
| 19 | + let rateApiKey: string = localStorage.getItem(EXCHANGE_RATE_API_KEY) || '' |
| 20 | + let bitcoinApiKey: string = localStorage.getItem(BITCOIN_API_KEY) || '' |
| 21 | + let password: string = '' |
| 22 | + let confirmPassword: string = '' |
17 | 23 |
|
18 | | - $: { |
| 24 | + $: if (error) { |
| 25 | + alert.set(error) |
19 | 26 | const isValidRate = !rateApiKey || isValidRateApiKey(rateApiKey) |
20 | 27 | const isValidBitcoin = !bitcoinApiKey || isValidBitcoinApiKey(bitcoinApiKey) |
21 | 28 | if (!isValidRate) { |
|
76 | 83 | error = $_('validBitcoinApiTip') |
77 | 84 | return |
78 | 85 | } |
| 86 | + if (password || confirmPassword) { |
| 87 | + if (password !== confirmPassword) { |
| 88 | + error = $_('passwordsDoNotMatch') |
| 89 | + return |
| 90 | + } |
| 91 | + if (password.length < 6) { |
| 92 | + error = $_('passwordTooShort') |
| 93 | + return |
| 94 | + } |
| 95 | + } |
79 | 96 | loading = true |
80 | 97 | error = '' |
81 | 98 | localStorage.setItem(EXCHANGE_RATE_API_KEY, rateApiKey) |
82 | 99 | localStorage.setItem(BITCOIN_API_KEY, bitcoinApiKey) |
| 100 | + if (password) { |
| 101 | + const hashedPassword = await hashPassword(password) |
| 102 | + await setPassword(hashedPassword) |
| 103 | + } |
83 | 104 | await fetchExchangeRates() |
84 | 105 | closeModal() |
85 | 106 | } catch (err) { |
|
95 | 116 | tabindex="-1" |
96 | 117 | class="fixed left-0 right-0 top-0 z-50 hidden h-[calc(100%-1rem)] w-full overflow-y-auto overflow-x-hidden p-4 md:inset-0 md:h-full"> |
97 | 118 | <div class="relative h-full w-full max-w-lg md:h-auto md:max-w-md"> |
98 | | - <div class="relative mt-16 rounded-lg bg-white pb-8 shadow"> |
| 119 | + <!-- Modal content --> |
| 120 | + <div class="relative mt-8 rounded-lg bg-white pb-8 shadow"> |
99 | 121 | <!-- Modal header --> |
100 | 122 | <div class="flex items-center justify-between rounded-t border-b p-5"> |
101 | 123 | <h3 class="flex items-center text-lg font-medium text-gray-900 md:text-base"> |
|
113 | 135 | <!-- Modal body --> |
114 | 136 | <div class="flex flex-col items-center justify-center p-6"> |
115 | 137 | <div class="module-warp"> |
116 | | - <label for="rateApiKey" class="custom-label"> |
| 138 | + <label for="rateApiKey" class="custom-label !leading-5"> |
117 | 139 | <a |
118 | 140 | target="_blank" |
119 | | - class="text-brand hover:text-mark leading-3" |
| 141 | + class="text-link hover:text-mark leading-3" |
120 | 142 | href="https://fine.niceshare.site/projects/wealth-tracker/#如何获取汇率-api-key"> |
121 | 143 | Exchange Rate <br /> |
122 | 144 | API Key |
123 | 145 | </a> |
124 | | - <i class="text-mark">*</i> |
125 | 146 | </label> |
126 | 147 | <input |
127 | 148 | type="text" |
|
131 | 152 | placeholder={$_('validRateApiTip')} /> |
132 | 153 | </div> |
133 | 154 |
|
134 | | - <div class="module-warp mt-4"> |
135 | | - <label for="bitcoinApiKey" class="custom-label"> |
| 155 | + <div class="module-warp"> |
| 156 | + <label for="bitcoinApiKey" class="custom-label !leading-5"> |
136 | 157 | <a |
137 | 158 | target="_blank" |
138 | | - class="text-brand hover:text-mark leading-3" |
| 159 | + class="text-link hover:text-mark leading-3" |
139 | 160 | href="https://api-ninjas.com/api/bitcoin"> |
140 | 161 | Bitcoin <br /> |
141 | 162 | API Key |
142 | | - <i class="text-mark">*</i> |
143 | 163 | </a> |
144 | 164 | </label> |
145 | 165 | <input |
|
149 | 169 | placeholder={$_('validBitcoinApiTip')} /> |
150 | 170 | </div> |
151 | 171 |
|
152 | | - {#if error} |
153 | | - <p class="text-sm text-red-500">{error}</p> |
| 172 | + {#if $isPasswordAllowed} |
| 173 | + <div class="inline-flex w-full items-center justify-center pb-4"> |
| 174 | + <hr class="my-6 h-px w-full border-0 bg-gray-200" /> |
| 175 | + <span |
| 176 | + class="text-warn absolute left-1/2 -translate-x-1/2 bg-white px-3 text-center font-medium leading-5"> |
| 177 | + {$_('setPasswordTip')} |
| 178 | + </span> |
| 179 | + </div> |
| 180 | + |
| 181 | + <div class="module-warp"> |
| 182 | + <label for="passwordInput" class="custom-label"> |
| 183 | + {$_('setPassword')} |
| 184 | + </label> |
| 185 | + <input |
| 186 | + id="passwordInput" |
| 187 | + type="password" |
| 188 | + class="custom-input" |
| 189 | + bind:value={password} |
| 190 | + placeholder={$_('passwordTip')} /> |
| 191 | + </div> |
| 192 | + |
| 193 | + <div class="module-warp"> |
| 194 | + <label for="confirmPasswordInput" class="custom-label"> |
| 195 | + {$_('confirmPassword')} |
| 196 | + </label> |
| 197 | + <input |
| 198 | + id="confirmPasswordInput" |
| 199 | + type="password" |
| 200 | + class="custom-input" |
| 201 | + bind:value={confirmPassword} |
| 202 | + placeholder={$_('confirmPasswordTip')} /> |
| 203 | + </div> |
| 204 | + {:else} |
| 205 | + <div class="module-warp"> |
| 206 | + <label for="allowPassword" class="custom-label"> |
| 207 | + {$_('allowPassword')} |
| 208 | + </label> |
| 209 | + <Toggle id="allowPassword" disabled checked={!$isPasswordAllowed} /> |
| 210 | + </div> |
154 | 211 | {/if} |
155 | 212 | </div> |
156 | 213 | <div class="flex items-center justify-center"> |
|
0 commit comments