Skip to content

Commit 970ffb1

Browse files
committed
feat: Store API token in local storage for easy access
1 parent 34421e2 commit 970ffb1

4 files changed

Lines changed: 114 additions & 19 deletions

File tree

src/App.vue

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,30 @@
99
</p>
1010
</InfoBanner>
1111
<UtilitySection title="API Configuration" title-heading-level="h2">
12-
<TextInput
13-
id="butter-api-token"
14-
type="password"
15-
placeholder="Enter your Butter CMS API Token"
16-
:required="true"
17-
v-model="store.token"
18-
>
19-
<template v-slot:label>Butter CMS API Token</template>
20-
<template v-slot:error v-if="!store.token"
21-
>Please provide your Butter CMS API Token</template
12+
<div class="app__token-input-container">
13+
<TextInput
14+
root-class="app__token-input"
15+
id="butter-api-token"
16+
type="password"
17+
placeholder="Enter your Butter CMS API Token"
18+
:required="true"
19+
:readonly="lockToken"
20+
v-model="store.token"
2221
>
23-
</TextInput>
22+
<template v-slot:label>Butter CMS API Token</template>
23+
<template v-slot:error v-if="!store.token"
24+
>Please provide your Butter CMS API Token</template
25+
>
26+
</TextInput>
27+
<button
28+
v-if="store.token"
29+
@click="toggleTokenLock"
30+
class="app__lock-button"
31+
:title="lockToken ? 'Unlock token' : 'Lock token'"
32+
>
33+
{{ lockToken ? '🔒' : '🔓' }}
34+
</button>
35+
</div>
2436
</UtilitySection>
2537

2638
<h2 style="font-weight: 500">Available Utilities</h2>
@@ -30,6 +42,7 @@
3042
</template>
3143

3244
<script setup lang="ts">
45+
import { ref, watch } from 'vue'
3346
import { useStore } from './stores/index'
3447
import Header from './components/Header.vue'
3548
import Footer from './components/Footer.vue'
@@ -39,9 +52,21 @@ import TextInput from './components/TextInput.vue'
3952
import SearchPages from './components/Utilities/SearchPages.vue'
4053
4154
const store = useStore()
55+
const lockToken = ref(localStorage.getItem('butter_cms_lock_token') === 'true')
56+
57+
watch(
58+
() => lockToken.value,
59+
(newValue) => {
60+
localStorage.setItem('butter_cms_lock_token', String(newValue))
61+
},
62+
)
63+
64+
function toggleTokenLock(): void {
65+
lockToken.value = !lockToken.value
66+
}
4267
</script>
4368

44-
<style lang="scss">
69+
<style lang="scss" scoped>
4570
#app {
4671
min-height: 100vh;
4772
display: flex;
@@ -55,4 +80,46 @@ main {
5580
margin: 0 auto;
5681
padding: 2rem 1.5rem;
5782
}
83+
84+
.app {
85+
&__token-input-container {
86+
display: flex;
87+
align-items: center;
88+
gap: 1rem;
89+
}
90+
91+
&__token-input {
92+
flex: 1;
93+
}
94+
95+
&__lock-button {
96+
margin-top: 1.5rem;
97+
width: 2.5rem;
98+
height: 2.5rem;
99+
padding: 0;
100+
background-color: #eee;
101+
border: 1px solid #b3bac2;
102+
border-radius: 6px;
103+
font-size: 1.25rem;
104+
cursor: pointer;
105+
display: flex;
106+
align-items: center;
107+
justify-content: center;
108+
transition: all 0.2s;
109+
font-family: monospace;
110+
111+
&:hover {
112+
background-color: #ddd;
113+
}
114+
115+
&:active {
116+
background-color: #a8aeb8;
117+
}
118+
119+
&:focus {
120+
outline: 2px solid #7c8db0;
121+
outline-offset: 2px;
122+
}
123+
}
124+
}
58125
</style>

src/components/Footer.vue

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,28 @@
2525
<p><strong>Last updated: January 2026</strong></p>
2626

2727
<h3>Data Collection</h3>
28-
<p>We do not collect, store, or transmit any data whatsoever. This includes:</p>
28+
<p>
29+
We do not collect, store on servers, or transmit any data to third parties. This
30+
includes:
31+
</p>
2932
<ul>
30-
<li>No API tokens or credentials</li>
31-
<li>No personal information</li>
33+
<li>No personal information transmitted to our servers</li>
3234
<li>No usage analytics or tracking</li>
33-
<li>No cookies or local storage</li>
3435
<li>No server-side logging</li>
36+
<li>No data shared with third-party services</li>
37+
</ul>
38+
39+
<h3>Local Storage</h3>
40+
<p>
41+
To improve your experience, we store your Butter CMS API token locally in your browser's
42+
localStorage. This is completely safe because:
43+
</p>
44+
<ul>
45+
<li>Data is stored only on your device, never on our servers</li>
46+
<li>Only your browser can access localStorage from this domain</li>
47+
<li>Other websites cannot access your stored token</li>
48+
<li>Clearing your browser data will remove the stored token</li>
49+
<li>You have full control and can delete it anytime</li>
3550
</ul>
3651

3752
<h3>How It Works</h3>

src/components/TextInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ $inputHeight: 2.5rem;
115115
116116
&:disabled,
117117
&:read-only {
118-
background-color: var(--j-global-grey-100);
118+
background-color: #eee;
119119
}
120120
121121
&[aria-invalid='true'] {

src/stores/index.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1-
import { ref } from 'vue'
1+
import { ref, watch } from 'vue'
22
import { defineStore } from 'pinia'
33

44
export const useStore = defineStore('store', () => {
5-
const token = ref('')
5+
// Initialize token from localStorage or empty string
6+
const token = ref(localStorage.getItem('butter_cms_token') || '')
7+
8+
// Watch for changes and save to localStorage
9+
watch(
10+
() => token.value,
11+
(newValue) => {
12+
if (newValue) {
13+
localStorage.setItem('butter_cms_token', newValue)
14+
} else {
15+
localStorage.removeItem('butter_cms_token')
16+
}
17+
},
18+
)
619

720
return { token }
821
})

0 commit comments

Comments
 (0)