Website updates
This commit is contained in:
parent
4b3e89fa59
commit
6b28ed61bd
19
Dockerfile
19
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM node as build
|
FROM node:20-alpine as build
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
ARG NODE_ENV=prod
|
ARG NODE_ENV=prod
|
||||||
@ -8,15 +8,24 @@ ENV NG_CLI_ANALYTICS=ci \
|
|||||||
NODE_OPTIONS=${NODE_OPTIONS}
|
NODE_OPTIONS=${NODE_OPTIONS}
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
RUN mkdir /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Install & build
|
# Build
|
||||||
RUN if [ ! -d "dist" ]; then npm ci && npm run build; fi
|
RUN if [ ! -d "dist" ]; then npm install && npm run build; fi
|
||||||
|
|
||||||
# Use Nginx to serve
|
# Use Nginx to serve
|
||||||
FROM nginx:1.20-alpine
|
FROM nginx:1.23-alpine
|
||||||
COPY --from=build /app/dist/browser /usr/share/nginx/html
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy aditional files
|
||||||
|
COPY package.json /usr/share/nginx/html
|
||||||
COPY docker/robots.txt /usr/share/nginx/html/robots.txt
|
COPY docker/robots.txt /usr/share/nginx/html/robots.txt
|
||||||
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# Setup environment varible script
|
||||||
|
COPY docker/setup-environment.sh /docker-entrypoint.d/setup-environment.sh
|
||||||
|
RUN chmod +x /docker-entrypoint.d/setup-environment.sh
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
7
docker/setup-environment.sh
Normal file
7
docker/setup-environment.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
JSON_STRING='window.env = { \
|
||||||
|
APP_POSTMAIL_ACCESS_TOKEN: "'"${APP_POSTMAIL_ACCESS_TOKEN}"'", \
|
||||||
|
}'
|
||||||
|
sed -i "s@<script id=\"environment\"></script>@<script>${JSON_STRING}</script>@" /usr/share/nginx/html/index.html
|
||||||
|
exec "$@"
|
12
index.html
12
index.html
@ -1,22 +1,24 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>ZaksCode</title>
|
<title>ZaksCode</title>
|
||||||
<link rel="icon" href="/logo.png">
|
<link rel="icon" href="/logo.png">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name=”robots” content=”index,nofollow” />
|
|
||||||
|
|
||||||
<meta property=”og:type” content=”website” />
|
<meta property=”og:type” content=”website” />
|
||||||
<meta property=”og:title” content=”Zakary Timson” />
|
<meta property=”og:title” content=”Zakary Timson” />
|
||||||
|
<!-- <meta name=”twitter:title” content=”Zakary Timson” />-->
|
||||||
|
<meta name="description" content="Devops & Software Engineer" />
|
||||||
<meta property=”og:description” content=”Devops & Software Engineer” />
|
<meta property=”og:description” content=”Devops & Software Engineer” />
|
||||||
|
<!-- <meta name=”twitter:description” content=”Devops & Software Engineer” />-->
|
||||||
<meta property=”og:image” content=”https://zakscode.com/cloud.gif” />
|
<meta property=”og:image” content=”https://zakscode.com/cloud.gif” />
|
||||||
|
<!-- <meta name=”twitter:image” content=”https://zakscode.com/cloud.gif” />-->
|
||||||
<meta property=”og:url” content=”https://zakscode.com” />
|
<meta property=”og:url” content=”https://zakscode.com” />
|
||||||
<meta property=”og:site_name” content=”ZaksCode” />
|
<meta property=”og:site_name” content=”ZaksCode” />
|
||||||
<!-- <meta name=”twitter:title” content=”Zakary Timson” />-->
|
|
||||||
<!-- <meta name=”twitter:description” content=”Devops & Software Engineer” />-->
|
<script id="environment"></script>
|
||||||
<!-- <meta name=”twitter:image” content=”https://zakscode.com/cloud.gif” />-->
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
BIN
public/logo.png
BIN
public/logo.png
Binary file not shown.
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 113 KiB |
@ -10,7 +10,7 @@ import Profile from '@/components/profile.vue';
|
|||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<div class="cap-width mb-3 bg-white">
|
<div class="cap-width mb-3 bg-white">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header class="p-3 mx-auto" style="background: #732222">
|
<header class="px-4 d-flex justify-content-center justify-content-sm-start" style="background: #732222">
|
||||||
<profile style="transform: translateY(-33%)" />
|
<profile style="transform: translateY(-33%)" />
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
23
src/components/card.vue
Normal file
23
src/components/card.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Icon from '@/components/icon.vue';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
color: {type: String, required: true},
|
||||||
|
icon: {type: String, required: true},
|
||||||
|
title: {type: String, required: true},
|
||||||
|
text: {type: String, required: true},
|
||||||
|
offset: {type: String, default: '0px'}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="d-flex flex-column align-items-center border mb-3 p-3" style="width: 240px">
|
||||||
|
<div class="m-3 p-3 rounded-circle text-white d-flex align-items-middle justify-content-center" :style="'height: 50px; width: 50px; background:' + color">
|
||||||
|
<icon :name="icon" :style="'margin-top:' + offset"/>
|
||||||
|
</div>
|
||||||
|
<h4>{{title}}</h4>
|
||||||
|
<p class="text-center">
|
||||||
|
{{text}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Icon from '@/components/icon.vue';
|
import Icon from '@/components/icon.vue';
|
||||||
|
import {environment} from '@/environments/environment';
|
||||||
import {ref} from 'vue';
|
import {ref} from 'vue';
|
||||||
|
|
||||||
const disable = ref(false);
|
const disable = ref(false);
|
||||||
@ -10,7 +11,7 @@ const data = ref({
|
|||||||
subject: '',
|
subject: '',
|
||||||
message: '',
|
message: '',
|
||||||
});
|
});
|
||||||
const errors = ref({
|
const errors = ref<any>({
|
||||||
banner: false,
|
banner: false,
|
||||||
name: false,
|
name: false,
|
||||||
email: false,
|
email: false,
|
||||||
@ -29,6 +30,27 @@ function validateEmail(email: string) {
|
|||||||
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
|
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function send(name: string, email: string, subject: string, message: string) {
|
||||||
|
function formEncode(data: any): string {
|
||||||
|
return Object.entries(data).map(([key, value]) =>
|
||||||
|
encodeURIComponent(key) + '=' + encodeURIComponent(<any>value)
|
||||||
|
).join('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch('https://postmail.invotes.com/send', {
|
||||||
|
method: 'post',
|
||||||
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||||
|
body: formEncode({
|
||||||
|
access_token: environment.postMailKey,
|
||||||
|
subject: `ZaksCode: ${subject}`,
|
||||||
|
text: `App: ZaksCode\nFrom: ${name} <${email}>\nSubject: ${subject}\n\nMessage:\n${message}`
|
||||||
|
})
|
||||||
|
}).then(async resp => {
|
||||||
|
if(!resp.ok) throw new Error(resp.statusText);
|
||||||
|
return await resp.text();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
disable.value = true;
|
disable.value = true;
|
||||||
const d = data.value;
|
const d = data.value;
|
||||||
@ -42,39 +64,51 @@ function submit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(errors.value.name || errors.value.email || errors.value.subject || errors.value.message) return disable.value = false;
|
if(errors.value.name || errors.value.email || errors.value.subject || errors.value.message) return disable.value = false;
|
||||||
// Email.send(d.name, d.email, d.subject, d.message).then(() => {
|
send(d.name, d.email, d.subject, d.message).then(() => {
|
||||||
// done.value = true;
|
done.value = true;
|
||||||
// }).catch(err => {
|
}).catch(err => {
|
||||||
// console.error(err);
|
console.error(err);
|
||||||
// errors.value.banner = err?.message || err.toString();
|
errors.value.banner = err?.message || err.toString();
|
||||||
// disable.value = false;
|
disable.value = false;
|
||||||
// });
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- Success Banner -->
|
||||||
<div v-if="done" class="alert alert-success">
|
<div v-if="done" class="alert alert-success">
|
||||||
<span>Success! We sent you a copy & we will be intouch shortly.</span>
|
<span>Success! We will be intouch shortly.</span>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Error Banner -->
|
||||||
<div v-if="errors?.banner" class="alert alert-danger">
|
<div v-if="errors?.banner" class="alert alert-danger">
|
||||||
{{ errors.banner }}
|
Error: {{ (errors as any).banner }}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Contact Form -->
|
||||||
<form>
|
<form>
|
||||||
<div class="d-flex flex-wrap justify-content-between mb-2">
|
<div class="d-flex flex-column flex-md-row flex-wrap justify-content-between">
|
||||||
<div class="input-group mb-2 mb-sm-0" style="width: 49%; min-width: 250px">
|
<!-- Name -->
|
||||||
|
<div class="mb-2 p-0 pe-md-1 p-md-0" style="flex: 1 0 0;">
|
||||||
|
<div class="input-group">
|
||||||
<span class="input-group-text"><icon name="user"/></span>
|
<span class="input-group-text"><icon name="user"/></span>
|
||||||
<input class="form-control" type="text" placeholder="Name" v-model="data.name" v-bind:class="{'is-invalid': errors?.name}" :disabled="!!user || disable" required>
|
<input class="form-control" type="text" placeholder="Name" v-model="data.name" v-bind:class="{'is-invalid': errors?.name}" :disabled="disable" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group" style="width: 49%; min-width: 250px">
|
</div>
|
||||||
|
<!-- Email -->
|
||||||
|
<div class="mb-2 p-0 ps-md-1" style="flex: 1 0 0;">
|
||||||
|
<div class="input-group">
|
||||||
<span class="input-group-text"><icon name="envelope"/></span>
|
<span class="input-group-text"><icon name="envelope"/></span>
|
||||||
<input class="form-control" type="email" placeholder="Email" v-model="data.email" v-bind:class="{'is-invalid': errors?.email}" :disabled="!!user || disable" required>
|
<input class="form-control" type="email" placeholder="Email" v-model="data.email" v-bind:class="{'is-invalid': errors?.email}" :disabled="disable" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Subject -->
|
||||||
<div class="input-group mb-2">
|
<div class="input-group mb-2">
|
||||||
<span class="input-group-text"><icon name="book"/></span>
|
<span class="input-group-text"><icon name="book"/></span>
|
||||||
<input class="form-control" type="text" placeholder="Subject" v-model="data.subject" v-bind:class="{'is-invalid': errors?.subject}" :disabled="disable" required>
|
<input class="form-control" type="text" placeholder="Subject" v-model="data.subject" v-bind:class="{'is-invalid': errors?.subject}" :disabled="disable" required>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Message Body -->
|
||||||
<textarea class="form-control" placeholder="Message" rows="5" v-model="data.message" v-bind:class="{'is-invalid': errors?.message}" :disabled="disable" required></textarea>
|
<textarea class="form-control" placeholder="Message" rows="5" v-model="data.message" v-bind:class="{'is-invalid': errors?.message}" :disabled="disable" required></textarea>
|
||||||
|
<!-- Buttons -->
|
||||||
<div class="text-end pt-3">
|
<div class="text-end pt-3">
|
||||||
<button type="button" class="btn rounded-pill ms-3" @click="reset()">Reset</button>
|
<button type="button" class="btn rounded-pill ms-3" @click="reset()">Reset</button>
|
||||||
<button type="button" class="btn btn-primary rounded-pill ms-3" @click="submit" :disabled="disable">Send Message</button>
|
<button type="button" class="btn btn-primary rounded-pill ms-3" @click="submit" :disabled="disable">Send Message</button>
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
footer {
|
footer {
|
||||||
background: #343a40;
|
background: #343a40;
|
||||||
color: darkgrey;
|
color: #A3A3A3;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #75B8FF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -232,6 +232,20 @@ window.cli['whoami'] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden-label {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute !important;
|
||||||
|
height: 1px;
|
||||||
|
width: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
|
||||||
|
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
|
||||||
|
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
|
||||||
|
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes blink-empty {
|
@keyframes blink-empty {
|
||||||
0% {background-size: 1px 1.1em;}
|
0% {background-size: 1px 1.1em;}
|
||||||
50% {background-size: 1px 1.1em;}
|
50% {background-size: 1px 1.1em;}
|
||||||
@ -245,7 +259,8 @@ window.cli['whoami'] = {
|
|||||||
<div class="console-output"></div>
|
<div class="console-output"></div>
|
||||||
<div class="console-input" @click=" focus()">
|
<div class="console-input" @click=" focus()">
|
||||||
<div class="console-input-prompt">root@{{hostname}}:~ #</div>
|
<div class="console-input-prompt">root@{{hostname}}:~ #</div>
|
||||||
<input class="console-input-field" type="text" @keydown="stdIn($event)">
|
<label for="console-input-field" class="hidden-label"><!-- Accessibility -->CLI Input</label>
|
||||||
|
<input id="console-input-field" class="console-input-field" type="text" @keydown="stdIn($event)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,7 +21,7 @@ import Icon from '@/components/icon.vue';
|
|||||||
</h2>
|
</h2>
|
||||||
<ul class="m-0 p-0 text-start" style="list-style: none">
|
<ul class="m-0 p-0 text-start" style="list-style: none">
|
||||||
<li><icon name="map-marker-alt" class="me-1"/> Toronto Ontario, Canada</li>
|
<li><icon name="map-marker-alt" class="me-1"/> Toronto Ontario, Canada</li>
|
||||||
<li><icon name="envelope" class="me-1"/> <a href="mailto:zaktimson@gmail.com">zaktimson@gmail.com</a></li>
|
<li><icon name="envelope" class="me-1"/> <a href="mailto:zaktimson@gmail.com" target="_blank">zaktimson@gmail.com</a></li>
|
||||||
<li><icon name="github" class="fa-brands me-1"/> <a href="https://github.com/ztimson" target="_blank">github.com/ztimson</a></li>
|
<li><icon name="github" class="fa-brands me-1"/> <a href="https://github.com/ztimson" target="_blank">github.com/ztimson</a></li>
|
||||||
<li><icon name="git-alt" class="fa-brands me-1"/> <a href="https://git.zakscode.com" target="_blank">git.zakscode.com</a></li>
|
<li><icon name="git-alt" class="fa-brands me-1"/> <a href="https://git.zakscode.com" target="_blank">git.zakscode.com</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -15,8 +15,7 @@ defineProps({
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-for="(p, i) in projects">
|
<div v-for="(p, i) in projects">
|
||||||
<hr v-if="i != 0">
|
<div class="d-flex align-items-center border p-2" :class="i == 0 ? '' : 'border-top-0'">
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="me-2">
|
<div class="me-2">
|
||||||
<img :src="p.icon || '/git.png'" alt="Logo" style="height: 40px; width: 40px;">
|
<img :src="p.icon || '/git.png'" alt="Logo" style="height: 40px; width: 40px;">
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,33 +1,30 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
const resume = 'https://drive.google.com/file/d/1N1L2SYvqY49OJAR97cjjHANj0ModmZSy/view?usp=drive_link';
|
||||||
.btn-outline-info:hover {
|
|
||||||
color: #ffffff;
|
const refrences = [
|
||||||
}
|
// ['Andre Mourinho', ''],
|
||||||
</style>
|
['CD Projekt Red', 'https://files.zakscode.com/share/N61Db3y0'],
|
||||||
|
['Chris Cartwright', 'https://files.zakscode.com/share/luyY49_N'],
|
||||||
|
['Garry Whyte', 'https://files.zakscode.com/share/zHjnHReT'],
|
||||||
|
['Linda Nicodemo', 'https://files.zakscode.com/share/1wKpkQzW'],
|
||||||
|
['Ray Power', 'https://files.zakscode.com/share/bTR2ab_P'],
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="d-block d-md-none">
|
<div class="d-block d-md-none">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<a class="btn btn-outline-primary w-100">CSV / Resume</a>
|
<a class="btn btn-outline-danger w-100" :href="resume" target="_blank">CSV / Resume</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group-vertical w-100" role="group">
|
<div class="btn-group-vertical w-100" role="group">
|
||||||
<a class="btn btn-outline-info">CD Projekt Red</a>
|
<a v-for="ref in refrences" class="btn btn-outline-primary" :href="ref[1]" target="_blank">{{ref[0]}}</a>
|
||||||
<a class="btn btn-outline-info">Chris Cartwright</a>
|
|
||||||
<a class="btn btn-outline-info">Garry Whyte</a>
|
|
||||||
<a class="btn btn-outline-info">Ray Power</a>
|
|
||||||
<a class="btn btn-outline-info">Linda Nicodemo</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-none d-md-block">
|
<div class="d-none d-md-block">
|
||||||
<a class="btn btn-outline-primary me-3">CSV / Resume</a>
|
<a class="btn btn-outline-danger me-3" :href="resume" target="_blank">CSV / Resume</a>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<a class="btn btn-outline-info">CD Projekt Red</a>
|
<a v-for="ref in refrences" class="btn btn-outline-primary" :href="ref[1]" target="_blank">{{ref[0]}}</a>
|
||||||
<a class="btn btn-outline-info">Chris Cartwright</a>
|
|
||||||
<a class="btn btn-outline-info">Garry Whyte</a>
|
|
||||||
<a class="btn btn-outline-info">Ray Power</a>
|
|
||||||
<a class="btn btn-outline-info">Linda Nicodemo</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
3
src/environments/environment.ts
Normal file
3
src/environments/environment.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const environment = {
|
||||||
|
postMailKey: (<any>window)?.env?.APP_POSTMAIL_KEY || import.meta.env.APP_POSTMAIL_ACCESS_TOKEN,
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
::-webkit-scrollbar { width: 10px; }
|
::-webkit-scrollbar { width: 10px; }
|
||||||
::-webkit-scrollbar-track { background: #333; }
|
::-webkit-scrollbar-track { background: #333; }
|
||||||
::-webkit-scrollbar-thumb { background: #555; border-radius: 5px }
|
::-webkit-scrollbar-thumb { background: #555; border-radius: 5px; }
|
||||||
::-webkit-scrollbar-thumb:hover { background: #aaa; }
|
::-webkit-scrollbar-thumb:hover { background: #aaa; }
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
@ -14,11 +14,11 @@ html, body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
font-family: Roboto,sans-serif;
|
font-family: Roboto,sans-serif;
|
||||||
background: #354B72 url(/cloud.gif) no-repeat fixed right 50% top -10vh;
|
background: #354B72 url('/cloud.gif') no-repeat fixed right 50% top -10vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not(.btn), a:not(.btn):visited {
|
a:not(.btn), a:not(.btn):visited {
|
||||||
color: #007bff;
|
color: #006FE6;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -1,81 +1,59 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import Card from '@/components/card.vue';
|
||||||
import Contact from '@/components/contact.vue';
|
import Contact from '@/components/contact.vue';
|
||||||
import Icon from '@/components/icon.vue';
|
|
||||||
import Konsole from '@/components/konsole.vue';
|
import Konsole from '@/components/konsole.vue';
|
||||||
import Projects from '@/components/projects.vue';
|
import Projects from '@/components/projects.vue';
|
||||||
import Refrences from '@/components/refrences.vue';
|
import Refrences from '@/components/refrences.vue';
|
||||||
|
import {ref} from 'vue';
|
||||||
|
|
||||||
const services: Projects[] = [
|
const services: Projects[] = [
|
||||||
{name: 'Formula Manager', icon: 'https://git.zakscode.com/avatars/7ec6bfd66b2bf9bad5c43c75a33f9cb3f6609b05c33a31f5d1e524a567cd09c1?size=280', link: 'https://screenprintingsuppliescanada.com/formulation-manager', description: 'Screen Printing Supplies'},
|
{name: 'Formula Manager', icon: 'https://git.zakscode.com/avatars/7ec6bfd66b2bf9bad5c43c75a33f9cb3f6609b05c33a31f5d1e524a567cd09c1?size=280', link: 'https://screenprintingsuppliescanada.com/formulation-manager', description: 'A web & computer application used by FH&Sons to record chemical formulas & distribute them to clients'},
|
||||||
{name: 'Map Alliance', icon: 'https://maps.zakscode.com/assets/images/logo.png', link: 'https://maps.zakscode.com', description: 'Online GIS & map editing solution'},
|
{name: 'Map Alliance', icon: 'https://maps.zakscode.com/assets/images/logo.png', link: 'https://maps.zakscode.com', description: 'An online GIS tool which enables users to view, edit & share various "marked-up" maps'},
|
||||||
{name: 'Phone Reminders', icon: 'https://phone-reminders.com/phone-reminders.png', link: 'https://phone-reminders.com', description: 'Send SMS & Voice call reminders from Google Calendar'},
|
{name: 'Phone Reminders', icon: 'https://phone-reminders.com/phone-reminders.png', link: 'https://phone-reminders.com', description: 'Automatically call & send SMS reminders to clients for events using Google Calendar'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const openSource: Projects[] = [
|
const openSource: Projects[] = [
|
||||||
{name: 'Formula Manager', icon: 'https://git.zakscode.com/avatars/7ec6bfd66b2bf9bad5c43c75a33f9cb3f6609b05c33a31f5d1e524a567cd09c1?size=280', link: 'https://screenprintingsuppliescanada.com/formulation-manager', description: 'Screen Printing Supplies'},
|
{name: 'ETF Demo', icon: 'https://git.zakscode.com/repo-avatars/0709db0c51d295d2d29b709865bd95f26e351f72a5c993ca63cd9ec4b4a07f43', link: 'https://etf.zakscode.com', source: 'https://git.zakscode.com/ztimson/etf-demo', description: 'Compare CSV files containing "Electronically Traded Funds" data (Check source for CSV files)'},
|
||||||
{name: 'Map Alliance', icon: 'https://maps.zakscode.com/assets/images/logo.png', link: 'https://maps.zakscode.com', description: 'Online GIS & map editing solution', source: 'https://google.com'},
|
{name: 'Legio 30', icon: 'https://git.zakscode.com/repo-avatars/f66e3d6f5ff4646b45e859f6bf00c0e0de0621d8a45a47481d53d67b67700f2a', link: 'https://legio-30.org', source: 'https://git.zakscode.com/ztimson/legio-30', description: 'Website for a non-profit Roman re-enactment group from Southern Ontario'},
|
||||||
{name: 'Phone Reminders', icon: 'https://phone-reminders.com/phone-reminders.png', link: 'https://phone-reminders.com', description: 'Send SMS & Voice call reminders from Google Calendar'},
|
{name: 'Pelican Landing', icon: 'https://git.zakscode.com/ztimson/pelican-landing/raw/branch/develop/src/assets/logo.png', link: 'https://pelican-landing.zakscode.com', source: 'https://git.zakscode.com/ztimson/pelican-landing', description: 'Business website for a hunting & fishing lodge on the Lage of Woods in Northern Ontario '},
|
||||||
|
{name: 'Persist', icon: 'https://git.zakscode.com/repo-avatars/89f6c36caf75762ed9f7f98b69044b7db30da5230be7c5cea54f8a1158f1669a', link: 'https://www.npmjs.com/package/@ztimson/persist', source: 'https://git.zakscode.com/ztimson/persist', description: 'Typescript library to sync variables with LocalStorage & persist state through page reloads'},
|
||||||
|
{name: 'PyBar', icon: 'https://git.zakscode.com/repo-avatars/002f97340c2781ccfa5d09fde97403fd499c39a9ad5675dc0edf05a8396e9ac5', link: 'https://git.zakscode.com/ztimson/py-bar', source: 'https://git.zakscode.com/ztimson/py-bar', description: 'Python library to display ASCII progress bars using iterators'},
|
||||||
|
{name: 'Transmute', icon: 'https://git.zakscode.com/repo-avatars/b497daaf22a214fe6d6cc35b8ec217cd22401b668dff93dcfcc7557bd8a46d96', link: 'https://git.zakscode.com/ztimson/transmute', source: 'https://git.zakscode.com/ztimson/transmute', description: 'Distributed video conversion tool with built in WebUI'},
|
||||||
|
{name: 'ZaksCode', icon: 'https://git.zakscode.com/repo-avatars/590279cb4b176c6a7924364c7b0ef78afa80696703abe5bef8d9ce7e12477f3d', link: 'https://zakscode.com', source: 'https://git.zakscode.com/ztimson/zakscode', description: 'Source code for this website, ZaksCode.com'},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Get repository count
|
||||||
|
let remainder = ref(0);
|
||||||
|
fetch('https://git.zakscode.com/api/v1/repos/search', {
|
||||||
|
method: 'get',
|
||||||
|
headers: {"Content-Type": "application/json"}
|
||||||
|
}).then(async repos => {
|
||||||
|
const data = (await repos.json())?.data;
|
||||||
|
remainder.value = data.length - openSource.length;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
|
<!-- Terminal -->
|
||||||
<konsole class="mb-5" style="max-height: 300px" />
|
<konsole class="mb-5" style="max-height: 300px" />
|
||||||
|
|
||||||
|
<!-- Steps -->
|
||||||
<div class="mb-5 pt-5">
|
<div class="mb-5 pt-5">
|
||||||
<h4 class="mb-0 text-center">Plan for Success</h4>
|
<h3 class="mb-0 text-center">Plan for Success</h3>
|
||||||
<hr class="mb-4">
|
<hr class="mb-4">
|
||||||
<div class="text-center my-5">
|
<div class="text-center my-5">
|
||||||
<img src="/cycle.svg" alt="Development Cycle" style="width: 100%; max-width: 600px; height: auto;">
|
<img src="/cycle.svg" alt="Development Cycle" style="width: 100%; max-width: 600px; height: auto;">
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
<div class="d-flex flex-wrap justify-content-around">
|
||||||
<div class="d-flex flex-column align-items-center border m-3 p-3 text-center" style="flex: 1 0 0;">
|
<card color="#6aa84f" icon="clipboard" offset="1px" title="Plan" text="Working with the client we will identify the goals of the project. This includes things like the target audience, use case, features, style, and delivery."/>
|
||||||
<div class="m-3 p-3 rounded-circle text-white d-flex align-items-middle justify-content-center" style="background: #6aa84f; height: 50px; width: 50px">
|
<card color="#6d9eeb" icon="code" offset="2px" title="Code" text="Goals are broken down into tasks and prioritized in our ticketing system. Using CI/CD, tasks are automatically deployed for testing as they are completed."/>
|
||||||
<icon name="clipboard"/>
|
<card color="#e69138" icon="message" offset="3px" title="Feedback" text="Clients are notified with the release notes and can test at their convince. Any critiques can be communicated directly to us or through our ticketing system."/>
|
||||||
</div>
|
<card color="#674ea7" icon="play" offset="2px" title="Release" text="Once all goals are complete we will work with you to deploy the product to any location. Once setup, future updates are automatically deployed to our clients."/>
|
||||||
<h5>Plan</h5>
|
|
||||||
<p class="text-center">
|
|
||||||
Working with the client we will identify the goals of the project. This includes things like the target audience, use case, features, style, and deployment strategy.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column align-items-center border m-3 p-3" style="flex: 1 0 0;">
|
|
||||||
<div class="m-3 p-3 rounded-circle text-white d-flex align-items-middle justify-content-center" style="background: #6d9eeb; height: 50px; width: 50px">
|
|
||||||
<icon name="code"/>
|
|
||||||
</div>
|
|
||||||
<h5>Develop</h5>
|
|
||||||
<p class="text-center">
|
|
||||||
Goals are broken down into tasks and are prioritized. Using CI/CD, tasks are automatically deployed for testing as they are completed.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column align-items-center border m-3 p-3" style="flex: 1 0 0;">
|
|
||||||
<div class="m-3 p-3 rounded-circle text-white d-flex align-items-middle justify-content-center" style="background: #e69138; height: 50px; width: 50px">
|
|
||||||
<icon name="message"/>
|
|
||||||
</div>
|
|
||||||
<h5>Feedback</h5>
|
|
||||||
<p class="text-center">
|
|
||||||
Clients are notified with the release notes and can test at their convince. Any critiques can be communicated directly to us or through our ticketing system.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column align-items-center border m-3 p-3" style="flex: 1 0 0;">
|
|
||||||
<div class="m-3 p-3 rounded-circle text-white" style="background: #674ea7; height: 50px; width: 50px">
|
|
||||||
<h5 class="m-0">4</h5>
|
|
||||||
</div>
|
|
||||||
<h5>Release</h5>
|
|
||||||
<p class="text-center">
|
|
||||||
Once all goals are complete we will work with you to deploy the product to any location. Once setup, future updates are automatically rolled out.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- About Section -->
|
||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<h3 class="mb-0">About</h3>
|
<h3 class="mb-0">About</h3>
|
||||||
<hr class="mb-4">
|
<hr class="mb-4">
|
||||||
@ -98,6 +76,7 @@ const openSource: Projects[] = [
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Projects List -->
|
||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<h3 class="m-0">Projects</h3>
|
<h3 class="m-0">Projects</h3>
|
||||||
<hr class="mb-4">
|
<hr class="mb-4">
|
||||||
@ -109,8 +88,10 @@ const openSource: Projects[] = [
|
|||||||
<h4 class="mb-3 text-muted">Open Source</h4>
|
<h4 class="mb-3 text-muted">Open Source</h4>
|
||||||
<projects :projects="openSource"/>
|
<projects :projects="openSource"/>
|
||||||
</div>
|
</div>
|
||||||
|
<a v-if="remainder" class="float-end m-2" href="https://git.zakscode.com/explore" target="_blank">See {{remainder}} More...</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact Form -->
|
||||||
<div>
|
<div>
|
||||||
<h3 class="m-0">Contact</h3>
|
<h3 class="m-0">Contact</h3>
|
||||||
<hr class="mb-4">
|
<hr class="mb-4">
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
"moduleResolution": "Node",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": [
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"module": "ESNext",
|
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"types": [
|
"types": [
|
||||||
"node"
|
"node"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import vue from '@vitejs/plugin-vue';
|
|
||||||
import {fileURLToPath, URL} from 'node:url';
|
|
||||||
|
|
||||||
import {defineConfig} from 'vite';
|
import {defineConfig} from 'vite';
|
||||||
|
import {fileURLToPath, URL} from 'node:url';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@ -12,5 +11,6 @@ export default defineConfig({
|
|||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
envPrefix: 'APP',
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user