Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/UI additions #12

Merged
merged 8 commits into from
Dec 20, 2024
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
### [1.0.5]
UI Enhancements:

* `ui/index.html`: Added a link to the Animate.css library for animation effects.
* [`ui/src/App.vue`: Integrated animation classes into various elements, including the header logo, buttons, and alerts.

Password Management Enhancements:
* `ui/src/pages/Create.vue`: Added functionality to toggle password visibility and generate random passwords, along with corresponding tooltips and animations.
404 Error Page Improvements:
* `ui/src/pages/Error404.vue`: Redesigned the 404 error page with a more user-friendly card layout, including an icon, message, and a button to navigate back home.

Other Enhancements:
* `ui/src/pages/Create.vue`, `ui/src/pages/View.vue`: Applied animation classes to various elements to provide a more dynamic user experience.

### [1.0.4]
- Reworked CD pipelines to follow semver tagging
- added version.yaml
Expand Down
4 changes: 4 additions & 0 deletions ui/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand Down
51 changes: 32 additions & 19 deletions ui/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<template>
<v-app>
<v-main>
<v-container fluid class="pa-0">
<v-main class="d-flex flex-column">
<v-container fluid class="pa-0 flex-grow-1">
<!-- Header -->
<v-toolbar color="primary" dark flat>
<v-toolbar-title>
<img src="./assets/Images/logo.png" alt="Logo" height="50" />
<router-link to="/" class="logo-link animate__animated animate__pulse">
<img src="./assets/Images/logo.png" alt="Logo" height="50" />
</router-link>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn to="/" text>
<v-btn to="/" text class="animate__animated animate__fadeIn">
<v-icon left>mdi-plus</v-icon> Create
</v-btn>
</v-toolbar>
Expand All @@ -17,22 +19,22 @@
<v-container class="mt-4">
<router-view />
</v-container>

<!-- Footer -->
<v-footer color="primary" dark class="justify-center mt-4">
<span>
© {{ new Date().getFullYear() }} GopherDrop |
<a
href="https://github.com/kek-Sec/gopherdrop"
target="_blank"
rel="noopener noreferrer"
class="text-white"
>
GitHub Repository
</a>
</span>
</v-footer>
</v-container>

<!-- Footer -->
<v-footer color="primary" dark class="justify-center">
<span>
© {{ new Date().getFullYear() }} GopherDrop |
<a
href="https://github.com/kek-Sec/gopherdrop"
target="_blank"
rel="noopener noreferrer"
class="text-white"
>
GitHub Repository
</a>
</span>
</v-footer>
</v-main>
</v-app>
</template>
Expand Down Expand Up @@ -65,4 +67,15 @@
.v-footer a:hover {
text-decoration: underline;
}

.logo-link {
display: inline-block;
text-decoration: none;
}

.v-main {
display: flex;
flex-direction: column;
min-height: 100vh;
}
</style>
56 changes: 48 additions & 8 deletions ui/src/pages/Create.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<v-container class="d-flex justify-center align-center fill-height">
<v-card class="pa-4" max-width="600" outlined>
<v-card class="pa-4 animate__animated animate__fadeIn" max-width="600" outlined>
<v-card-title class="text-h5 text-center">Create a New Secret 🔑</v-card-title>
<v-card-text>
<v-form @submit.prevent="handleSubmit">
Expand Down Expand Up @@ -30,8 +30,26 @@
<v-text-field
label="Password (optional)"
v-model="password"
type="password"
></v-text-field>
:type="showPassword ? 'text' : 'password'"
>
<template v-slot:append-inner>
<v-tooltip text="Toggle Password Visibility">
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on" @click="togglePasswordVisibility" size="small">
<v-icon>{{ showPassword ? 'mdi-eye-off' : 'mdi-eye' }}</v-icon>
</v-btn>
</template>
</v-tooltip>

<v-tooltip text="Generate Random Password">
<template v-slot:activator="{ on, attrs }">
<v-btn icon color="primary" v-bind="attrs" v-on="on" @click="generatePassword" size="small" style="margin-left: 4px">
<v-icon>mdi-refresh</v-icon>
</v-btn>
</template>
</v-tooltip>
</template>
</v-text-field>

<v-select
label="Expiration"
Expand All @@ -48,18 +66,22 @@

<v-btn type="submit" color="primary" class="mt-4" block>Create</v-btn>

<v-alert v-if="errorMessage" type="error" class="mt-4">
<v-alert v-if="errorMessage" type="error" class="mt-4 animate__animated animate__bounceIn">
{{ errorMessage }}
</v-alert>
</v-form>

<v-alert v-if="resultHash" type="success" class="mt-4">
<v-alert v-if="resultHash" type="success" class="mt-4 animate__animated animate__fadeIn">
Secret Created! Share this link:<br />
<div class="d-flex align-center mt-2">
<v-chip class="mr-2">{{ baseUrl }}/view/{{ resultHash }}</v-chip>
<v-btn icon @click="copyLink" color="light-green">
<v-icon>mdi-content-copy</v-icon>
</v-btn>
<v-tooltip text="Copy Link to Clipboard">
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on" @click="copyLink" color="white">
<v-icon color="black">mdi-content-copy</v-icon>
</v-btn>
</template>
</v-tooltip>
</div>
<v-snackbar v-model="snackbar" timeout="2000">
Link copied to clipboard!
Expand All @@ -83,6 +105,7 @@ const type = ref('text')
const textSecret = ref('')
const fileBlob = ref(null)
const password = ref('')
const showPassword = ref(false)
const oneTime = ref(false)
const expires = ref('24h')
const errorMessage = ref('')
Expand Down Expand Up @@ -162,6 +185,23 @@ function copyLink() {
navigator.clipboard.writeText(link)
snackbar.value = true
}

function generatePassword() {
const length = 12
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+'
let generatedPassword = ''
const randomValues = new Uint32Array(length)
window.crypto.getRandomValues(randomValues)
for (let i = 0; i < length; i++) {
const randomIndex = randomValues[i] % charset.length
generatedPassword += charset[randomIndex]
Fixed Show fixed Hide fixed
}
password.value = generatedPassword
}

function togglePasswordVisibility() {
showPassword.value = !showPassword.value
}
</script>

<style scoped>
Expand Down
51 changes: 31 additions & 20 deletions ui/src/pages/Error404.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
<template>
<div class="error-page">
<h2>Page Not Found</h2>
<p>The requested page does not exist.</p>
<router-link to="/">Go Back</router-link>
</div>
</template>

<script setup>
/**
* Basic 404 error page.
*/
</script>

<style scoped>
.error-page {
text-align: center;
margin-top: 2rem;
}
</style>

<v-container class="error-page d-flex flex-column align-center justify-center fill-height">
<v-card class="pa-6 text-center" elevation="4" max-width="500">
<v-icon size="80" color="red">mdi-alert-circle-outline</v-icon>
<h2 class="text-h4 mt-4">Oops! Page Not Found</h2>
<p class="mt-2 mb-4 text-body-1">
The page you are looking for does not exist or has been moved.
</p>
<v-btn to="/" color="primary" large>
<v-icon left>mdi-home</v-icon>
Go Home
</v-btn>
</v-card>
</v-container>
</template>

<script setup>
/**
* 404 Error Page Component.
*/
</script>

<style scoped>
.error-page {
min-height: 100vh;
}

.v-card {
background-color: #f5f5f5;
border-radius: 12px;
}
</style>
9 changes: 5 additions & 4 deletions ui/src/pages/View.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<v-container class="d-flex justify-center align-center fill-height">
<v-card class="pa-4" max-width="600" outlined>
<v-card class="pa-4 animate__animated animate__fadeIn" max-width="600" outlined>
<v-card-title class="text-h5 text-center">View Secret</v-card-title>
<v-card-text>
<v-alert v-if="errorMessage" type="error" class="mb-4">
Expand All @@ -19,9 +19,10 @@
type="password"
prepend-icon="mdi-lock"
required
class="animate__animated animate__fadeIn"
></v-text-field>

<v-btn type="submit" color="primary" block>Load Secret</v-btn>
<v-btn type="submit" color="primary" class="animate__animated animate__fadeIn" block>Load Secret</v-btn>
</v-form>

<div v-if="secretLoaded">
Expand All @@ -32,7 +33,7 @@

<!-- Download button for file secret -->
<div v-if="fileBlob">
<v-btn color="primary" @click="downloadFile" block>
<v-btn color="primary" @click="downloadFile" block class="animate__animated animate__fadeIn">
<v-icon left>mdi-download</v-icon> Download File
</v-btn>
</div>
Expand All @@ -43,7 +44,7 @@
</v-btn>

<v-snackbar v-model="snackbar" timeout="2000">
Link copied to clipboard!
Text copied to clipboard!
</v-snackbar>
</div>
</v-card-text>
Expand Down
2 changes: 1 addition & 1 deletion version.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#Application version following https://semver.org/
version: 1.0.4
version: 1.0.5
Loading