Skip to content

Commit

Permalink
Merge pull request #34 from imRohan/develop
Browse files Browse the repository at this point in the history
[Release] 1.2.0 - SEO + Status Page
  • Loading branch information
Rohan Likhite authored May 22, 2020
2 parents 7fdf3c6 + 7ba5e1b commit a92eb31
Show file tree
Hide file tree
Showing 24 changed files with 335 additions and 68 deletions.
7 changes: 4 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pantry</title>
<title>Pantry - Free JSON Storage API</title>
<meta name="author" content="Rohan Likhite">
<meta name="description" content="Free Perishable Data Storage">
<meta name="keywords" content="">
<meta name="description" content="Free JSON storage API for personal
projects, helps developers build projects quickly">
<meta name="keywords" content="free json storage api">
<link rel="shortcut icon" href="" type="image/vnd.microsoft.icon">
</head>
<body>
Expand Down
37 changes: 37 additions & 0 deletions src/app/components/landingRight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const landingRight = {
data() {
return {
apiPath: API_PATH,
systemStatus: null,
signup: {
email: null,
accountName: null,
Expand All @@ -39,6 +40,26 @@ const landingRight = {
copyPantryIdMessage: 'copy',
}
},
filters: {
capitalizeKey(key) {
if (!key) { return '' }

const _key = key.toString()
return(`${_key.charAt(0).toUpperCase()}${_key.slice(1)}`)
},
},
computed: {
isStatusPositive() {
if (!this.systemStatus) { return false }

const _statusArray = Object.values(this.systemStatus)
const _operational = _statusArray.filter((status) => {
return status
})

return _operational.length === _statusArray.length
},
},
methods: {
async createNewPantry() {
const { accountName, email } = this.signup
Expand Down Expand Up @@ -116,9 +137,25 @@ const landingRight = {
this.fetchPantry(_pantryId)
}
},
async fetchStatus() {
const { data } = await axios({
method: 'GET',
url: `${API_PATH}/system/status`,
})
this.systemStatus = data
},
getStatusString() {
const _positiveMessage = 'All Services Operational'
const _negativeMessage = 'Pantry is Experiencing Issues'

const _positiveStatus = this.isStatusPositive

return _positiveStatus ? _positiveMessage : _negativeMessage
},
},
mounted() {
this.fetchURLParams()
this.fetchStatus()
},
}

Expand Down
3 changes: 3 additions & 0 deletions src/app/components/topbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const topbar = {
template: topbarTemplate,
props: [],
methods: {
showStatus() {
this.$emit('change-view', IView.status)
},
showAbout() {
this.$emit('change-view', IView.about)
},
Expand Down
11 changes: 5 additions & 6 deletions src/app/scss/_app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,11 @@ li {
margin-bottom: 1em;
}

.slide-fade-enter-active, .slide-fade-leave-active {
transition: all .5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
table {
border: 1px solid $secondary-color;
width: 100%;
}

.slide-fade-enter, .slide-fade-leave-to {
opacity: 0;
td {
padding: 1em;
}


18 changes: 18 additions & 0 deletions src/app/scss/_banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.banner {
&__container {
background: $green;
padding: 1em;
max-width: 100%;
color: $white;
margin-bottom: 1em;
}
&--red {
background: $red,
}

&--transparent {
background: none;
color: $secondary-color;
border: 1px solid $secondary-color;
}
}
13 changes: 13 additions & 0 deletions src/app/scss/_text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,17 @@ a:any-link {
&--dark {
color: $primary-color !important;
}
&--green {
color: $green !important;
}
&--red {
color: $red !important;
}
&--bold {
font-weight: 700
}
&--right {
text-align: right;
float: right;
}
}
14 changes: 10 additions & 4 deletions src/app/scss/_variables.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// Colors
$white: #FFFFFF;
$background: #FFE2C9;
$primary-color: #8CA994;
$secondary-color: #F5BDA4;
$text-color: #08004B;
$green: #8CA994;
$orange: #FFE2C9;
$darkOrange: #E0AC95;
$purple: #08004B;
$red: #F56969;

$background: $orange;
$primary-color: $green;
$secondary-color: $darkOrange;
$text-color: $purple;

// Dimensions
$topbar-height: 3em;
Expand Down
1 change: 1 addition & 0 deletions src/app/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
@import 'topbar';
@import 'bottomBar';
@import 'basket';
@import 'banner'
114 changes: 73 additions & 41 deletions src/app/templates/landingRight.html
Original file line number Diff line number Diff line change
@@ -1,41 +1,51 @@
<div class="landing__right">
<template v-if="view === 'home'">
<h1>
Unburden yourself from data storage woes.
<template v-if="!showNameField">
Unburden yourself from data storage woes.
</template>
<template v-else>
Almost there, just one more step!
</template>
</h1>
<p>
Focus your efforts on building your next project and leave
the data storage to us. With free NoSQL cloud storage for you and
your users, Pantry speeds up development time letting you
build awesome things - fast!
<template v-if="!showNameField">
Focus your efforts on building your next project and leave the
data storage to us. We'll help speed up your development time
letting you build awesome things fast! Try out our API, and start
securely storing data on the cloud for free!
</template>
<template v-else>
Let's give your pantry a name! This could be the name of your project
or anything that means something to you. Please keep in mind that
inactive pantries and their baskets will be deleted automatically.
</template>
</p>
<transition name="slide-fade" mode="out-in">
<div v-if="!showNameField" key="enterEmail">
<div class="input__container">
<input v-model="signup.email" placeholder="[email protected]">
<button @click="enterPantryName" :disabled="!signupValid()">
Create a Pantry
</button>
</div>
<p v-if="signup.email && !signupValid()" class="text--light">
Sorry, but that email is invalid.
</p>
<p v-else class="text--light">
Don't worry, we'll only contact you if its important.
</p>
<div v-if="!showNameField">
<div class="input__container">
<input v-model="signup.email" placeholder="[email protected]">
<button @click="enterPantryName" :disabled="!signupValid()">
Create a Pantry
</button>
</div>
<div v-else key="enterPantryName">
<div class="input__container">
<input v-model="signup.accountName" placeholder="">
<button @click="createNewPantry" :disabled="!signupNameValid()">
Name your Pantry
</button>
</div>
<p class="text--light">
Give your Pantry a creative name
</p>
<p v-if="signup.email && !signupValid()" class="text--light">
Sorry, but that email is invalid.
</p>
<p v-else class="text--light">
Don't worry, we'll only contact you if its important.
</p>
</div>
<div v-else>
<div class="input__container">
<input v-model="signup.accountName" placeholder="">
<button @click="createNewPantry" :disabled="!signupNameValid()">
Name your Pantry
</button>
</div>
</transition>
<p class="text--light">
Give your Pantry a creative name
</p>
</div>
</template>

<template v-if="view === 'created'">
Expand Down Expand Up @@ -87,6 +97,27 @@ <h2>Contribute</h2>
</a>
</template>

<template v-if="view === 'status'">
<h1>
System Status
</h1>
<div :class="isStatusPositive ? 'banner--green' : 'banner--red'"
class="banner__container">
{{ getStatusString() }}
</div>

<template v-for="(status, entity) in systemStatus">
<div class="banner__container banner--transparent">
<span class="text--bold">
{{ entity | capitalizeKey }}
</span>
<span :class="status ? 'text--green' : 'text--red'" class="text--right">
{{ status ? 'Operational' : 'Down' }}
</span>
</div>
</template>
</template>

<template v-if="view === 'dashboard'">
<template v-if="pantry.data">
<h1>
Expand All @@ -97,23 +128,24 @@ <h2>
{{pantry.data.baskets.length}}
{{pantry.data.baskets.length > 1 ? 'Baskets' : 'Basket' }}
in this Pantry
- {{pantry.data.percentFull}}% Full
</h2>
<div class="basket__container">
<ul>
<template v-for="basketName in pantry.data.baskets">
<li class="text__container">
{{ basketName }}
<span class="text__button" @click="toggleBasket(basketName)">
{{ activeBasket === basketName ? 'hide' : 'show' }}
</span>
<template v-if="activeBasket === basketName">
<div class="basket__payload-container">
<json-view
:deep="1"
:showLength="true"
:data="basket"/>
</div>
</template>
<span class="text__button" @click="toggleBasket(basketName)">
{{ activeBasket === basketName ? 'hide' : 'show' }}
</span>
<template v-if="activeBasket === basketName">
<div class="basket__payload-container">
<json-view
:deep="1"
:showLength="true"
:data="basket"/>
</div>
</template>
</li>
</template>
</ul>
Expand Down
3 changes: 3 additions & 0 deletions src/app/templates/topbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<div class="topbar__link" @click="showAbout">
About
</div>
<div class="topbar__link" @click="showStatus">
Status
</div>
<div class="topbar__link" @click="showDocs">
Documentation
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import logService = require('../services/logger')
import mailer = require('../services/mailer')

// Interfaces
import { IAccount, IAccountPublic } from '../interfaces/account'
import { IAccountParams, IAccountPublic } from '../interfaces/account'

// Logger setup
const logger = new logService('Account Controller')

class AccountController {
public static async create(params: IAccount): Promise<string> {
public static async create(params: IAccountParams): Promise<string> {
try {
const _account = new Account(params)
const _accountUUID = await _account.store()
Expand Down
39 changes: 39 additions & 0 deletions src/controllers/system.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Extarnal Libs

// External Files
import dataStore = require('../services/dataStore')
import logService = require('../services/logger')

// Interfaces
import { ISystemStatus } from '../interfaces/system'

// Logger setup
const logger = new logService('System Controller')

class SystemController {
public static async getStatus(): Promise<ISystemStatus> {
try {
const _dataStoreStatus = await dataStore.ping()

const _status = {
website: true,
api: true,
dataStore: _dataStoreStatus,
}

logger.info('System status retrieved')
return _status
} catch (error) {
logger.error(`System status retrieval failed: ${error.message}`)

const _errorStatus = {
website: true,
api: true,
dataStore: false,
}
return _errorStatus
}
}
}

export = SystemController
Loading

0 comments on commit a92eb31

Please sign in to comment.