refactor: theme, colors

This commit is contained in:
Zack Spear
2023-06-21 17:59:59 -05:00
committed by Zack Spear
parent 0ff9dba5a8
commit 89736767a1
23 changed files with 106 additions and 58 deletions

View File

@@ -37,21 +37,39 @@ if (state === 'TRIAL') expireTime = Date.now() + 60 * 60 * 1000; // in 1 hour
if (state === 'EEXPIRED') expireTime = uptime; // 1 hour ago
const serverState = {
// avatar: '',
avatar: 'https://source.unsplash.com/300x300/?portrait',
name: 'DevServer9000',
description: 'Fully automated media server',
guid: randomGuid,
deviceCount: 8,
"apiKey": "unupc_12312313123",
"avatar": "https://source.unsplash.com/300x300/?portrait",
"description": "DevServer9000",
"deviceCount": "3",
expireTime,
lanIp: '192.168.0.1',
locale: 'en',
pluginInstalled: true,
registered: true,
site: 'http://localhost:4321',
state,
"flashProduct": "SanDisk_3.2Gen1",
"flashVendor": "USB",
"guid": "0781-5583-8355-81071A2B0211",
"keyfile": "DUMMY_KEYFILE",
"lanIp": "192.168.254.36",
"license": "",
"locale": "en_US",
"name": "fuji",
// "pluginInstalled": "dynamix.unraid.net.staging.plg",
"pluginInstalled": false,
"registered": true,
"regGen": 0,
"regGuid": "0781-5583-8355-81071A2B0211",
"site": "http://localhost:4321",
"state": state,
"theme": {
"banner": false,
"bannerGradient": false,
"bgColor": "",
"descriptionShow": true,
"metaColor": "",
"name": "black",
// "name": "white",
"textColor": ""
},
uptime,
username: 'zspearmint'
"username": "zspearmint",
"wanFQDN": ""
};
export default serverState;

View File

@@ -27,7 +27,7 @@ const button = computed(() => {
<template>
<div class="whitespace-normal flex flex-col gap-y-16px max-w-3xl">
<span v-if="stateData.error" class="text-red font-semibold leading-8">
<span v-if="stateData.error" class="text-unraid-red font-semibold leading-8">
{{ stateData.heading }}
<br />
{{ stateData.message }}
@@ -38,7 +38,7 @@ const button = computed(() => {
:is="button.click ? 'button' : 'a'"
@click="button.click()"
rel="noopener noreferrer"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60"
target="_blank"
download
>

View File

@@ -17,13 +17,13 @@ const { avatar, pluginInstalled, registered, username } = storeToRefs(serverStor
// :class="{
// 'ml-8px': usernameButtonText,
// 'bg-transparent': registered && !avatarFail,
// 'bg-gradient-to-r from-red to-orange': !registered || avatarFail,
// 'bg-gradient-to-r from-unraid-red to-orange': !registered || avatarFail,
// }"
// :title="usernameButtonTitle"
</script>
<template>
<figure class="group relative z-0 flex items-center justify-center w-36px h-36px rounded-full bg-gradient-to-r from-red to-orange">
<figure class="group relative z-0 flex items-center justify-center w-36px h-36px rounded-full bg-gradient-to-r from-unraid-red to-orange">
<img
v-if="avatar && pluginInstalled && registered"
:src="avatar"

View File

@@ -16,9 +16,9 @@ const props = withDefaults(defineProps<Props>(), {
const classes = computed(() => {
switch (props.style) {
case 'fill':
return 'text-white bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60';
return 'text-white bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60';
case 'outline':
return 'text-orange-dark bg-gradient-to-r from-transparent to-transparent border border-solid border-orange-dark hover:text-white focus:text-white hover:from-red hover:to-orange focus:from-red focus:to-orange hover:border-transparent focus:border-transparent';
return 'text-orange-dark bg-gradient-to-r from-transparent to-transparent border border-solid border-orange-dark hover:text-white focus:text-white hover:from-unraid-red hover:to-orange focus:from-unraid-red focus:to-orange hover:border-transparent focus:border-transparent';
}
});
</script>

View File

@@ -20,7 +20,7 @@ const downloadUrl = computed(() => new URL(`/graphql/api/logs?apiKey=${apiKey.va
<a
:href="downloadUrl.toString()"
rel="noopener noreferrer"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60"
target="_blank"
download
>

View File

@@ -20,7 +20,7 @@ const { keyActions } = storeToRefs(useServerStore());
:is="action.click ? 'button' : 'a'"
@click="action.click()"
rel="noopener noreferrer"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60"
target="_blank"
download
>

View File

@@ -5,15 +5,19 @@ import useFocusTrap from '~/composables/useFocusTrap';
export interface Props {
description?: string;
error?: boolean;
maxWidth?: string;
open?: boolean;
showCloseX?: boolean;
success?: boolean;
title?: string;
}
const props = withDefaults(defineProps<Props>(), {
error: false,
maxWidth: 'sm:max-w-lg',
open: false,
showCloseX: false,
success: false,
});
watchEffect(() => {
// toggle body scrollability
@@ -62,9 +66,17 @@ const ariaLablledById = computed((): string|undefined => props.title ? `ModalTit
leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95"
>
<div :class="maxWidth" class="text-alpha bg-beta relative transform overflow-hidden rounded-lg px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:p-6">
<div
:class="[
maxWidth,
error ? 'shadow-unraid-unraid-red/30' : '',
success ? 'shadow-green-400-400/30' : '',
!error && !success ? 'shadow-orange/10' : '',
]"
class="text-alpha bg-beta relative transform overflow-hidden rounded-lg px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:p-6"
>
<div v-if="showCloseX" class="absolute z-20 right-0 top-0 hidden pt-2 pr-2 sm:block">
<button @click="closeModal" type="button" class="rounded-md bg-alpha text-gray-400 p-2 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
<button @click="closeModal" type="button" class="rounded-md text-alpha bg-beta p-2 hover:text-white focus:text-white hover:bg-unraid-red focus:bg-unraid-red focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
<span class="sr-only">Close</span>
<XMarkIcon class="h-6 w-6" aria-hidden="true" />
</button>

View File

@@ -5,6 +5,7 @@ import { OnClickOutside } from '@vueuse/components'
import { useCallbackStore } from '~/store/callbackActions';
import { useDropdownStore } from '~/store/dropdown';
import { useServerStore } from '~/store/server';
import { useThemeStore } from '~/store/theme';
import type { Server } from '~/types/server';
import 'tailwindcss/tailwind.css';
import '~/assets/main.css';
@@ -19,7 +20,8 @@ const dropdownStore = useDropdownStore()
const serverStore = useServerStore();
const { dropdownVisible } = storeToRefs(dropdownStore);
const { name, description, lanIp, theme, stateData } = storeToRefs(serverStore);
const { name, description, lanIp } = storeToRefs(serverStore);
const { bannerGradient, theme } = storeToRefs(useThemeStore());
/**
* Close dropdown when clicking outside
@@ -81,13 +83,15 @@ onBeforeMount(() => {
<template>
<div id="UserProfile" class="text-alpha relative z-20 flex flex-col h-full gap-y-4px pt-4px pr-16px pl-40px">
<div class="text-gamma text-12px text-right font-semibold leading-normal flex flex-row items-baseline justify-end gap-x-12px">
<div v-if="bannerGradient" class="absolute z-0 w-[125%] top-0 bottom-0 right-0" :style="bannerGradient" />
<div class="text-gamma text-12px text-right font-semibold leading-normal relative z-10 flex flex-row items-baseline justify-end gap-x-12px">
<UpcUptimeExpire />
<span>&bull;</span>
<UpcServerState />
</div>
<div class="relative z-0 flex flex-row items-center justify-end gap-x-16px h-full">
<div class="relative z-10 flex flex-row items-center justify-end gap-x-16px h-full">
<h1 class="text-alpha relative text-18px border-t-0 border-r-0 border-l-0 border-b-2 border-transparent">
<template v-if="description && theme?.descriptionShow">
<span>{{ description }}</span>
@@ -96,7 +100,7 @@ onBeforeMount(() => {
<button @click="copyLanIp()" :title="`Click to Copy LAN IP ${lanIp}`">{{ name }}</button>
<span
v-show="copied || showCopyNotSupported"
class="text-white text-12px leading-none py-4px px-8px absolute right-0 bg-gradient-to-r from-red to-orange text-center block rounded"
class="text-white text-12px leading-none py-4px px-8px absolute right-0 bg-gradient-to-r from-unraid-red to-orange text-center block rounded"
>
<template v-if="copied">{{ 'LAN IP Copied' }}</template>
<template v-else>LAN IP: <span class="select-all">{{ lanIp }}</span></template>

View File

@@ -27,10 +27,10 @@ const { keyUrl, installing, success } = storeToRefs(installKeyStore);
const heading = computed(() => callbackLoading.value ? 'Performing actions' : 'Finished performing actions');
const subheading = computed(() => callbackLoading.value ? 'Please keep this window open' : '');
const close = () => {
if (callbackLoading.value) return console.debug('[close] not allowed');
callbackActionsStore.closeCallbackFeedback();
};
// const close = () => {
// if (callbackLoading.value) return console.debug('[close] not allowed');
// callbackActionsStore.closeCallbackFeedback();
// };
// @close="close"
// :show-close-x="!callbackLoading"
@@ -43,8 +43,10 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
<Modal
:open="open"
max-width="max-w-640px"
:error="success === false || updateSuccess === false"
:success="success === true || updateSuccess === true"
>
<div class="text-16px text-center relative w-full flex flex-col gap-y-16px">
<div class="text-16px text-center relative w-full min-h-[20vh] flex flex-col justify-between gap-y-16px">
<header>
<h1 class="text-24px font-semibold">{{ heading }}</h1>
<p v-if="subheading" class="text-16px opacity-80">{{ subheading }}</p>
@@ -56,13 +58,13 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
<p v-if="installing || callbackLoading">Installing License Key</p>
<template v-else>
<div v-if="success === true" class="flex items-center justify-center gap-x-8px">
<CheckCircleIcon class="fill-green w-24px" />
<CheckCircleIcon class="fill-green-400 w-24px" />
<p>Installed License Key</p>
</div>
<template v-else-if="success === false">
<div class="flex items-center justify-center gap-x-8px">
<XCircleIcon class="fill-red w-24px" />
<p class="text-red italic">License Key Install Failed</p>
<XCircleIcon class="fill-unraid-red w-24px" />
<p class="text-unraid-red italic">License Key Install Failed</p>
</div>
<button v-if="isSupported" @click="copy(keyUrl)">{{ copied ? 'Copied' : 'Copy Key URL' }}</button>
<p v-else>Copy your Key URL: {{ keyUrl }}</p>
@@ -75,12 +77,12 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
<p v-if="updating || callbackLoading">Updating Connect account config</p>
<template v-else>
<div v-if="updateSuccess === true" class="flex items-center justify-center gap-x-8px">
<CheckCircleIcon class="fill-green w-24px" />
<CheckCircleIcon class="fill-green-400 w-24px" />
<p>Connect config updated</p>
</div>
<div v-else-if="updateSuccess === false" class="flex items-center justify-center gap-x-8px">
<XCircleIcon class="fill-red w-24px" />
<p class="text-red italic">Connect config update failed</p>
<XCircleIcon class="fill-unraid-red w-24px" />
<p class="text-unraid-red italic">Connect config update failed</p>
</div>
</template>
</template>

View File

@@ -16,8 +16,8 @@ const apiLoading = ref(false);
<span class="text-12px italic opacity-80">{{ 'Loading Connect status…' }}</span>
</template>
<span v-else class="w-full flex flex-row justify-start items-center gap-x-8px">
<ExclamationTriangleIcon v-if="onlineStatus !== 'online'" class="text-red w-16px h-16px" />
<span v-else class="block w-12px h-12px bg-green rounded-full"></span>
<ExclamationTriangleIcon v-if="onlineStatus !== 'online'" class="text-unraid-red w-16px h-16px" />
<span v-else class="block w-12px h-12px bg-green-400 rounded-full"></span>
<span>{{ onlineStatus !== 'online' ? 'Disconnected' : 'Connected' }}</span>
</span>
</li>

View File

@@ -22,7 +22,7 @@ const links = ref<UserProfileLink[]>([
</script>
<template>
<ul v-if="stateData.error" class="list-reset flex flex-col gap-y-4px -mx-8px mb-4px py-12px px-16px bg-red/40 rounded">
<ul v-if="stateData.error" class="list-reset flex flex-col gap-y-4px -mx-8px mb-4px py-12px px-16px bg-unraid-red/40 rounded">
<h3 class="text-18px">{{ stateData.heading }}</h3>
<p class="text-14px opacity-85">{{ stateData.message }}</p>
<li v-for="(link, index) in links" :key="`link_${index}`" class="-mx-8px">

View File

@@ -22,8 +22,8 @@ const showExternalIconOnHover = computed(() => props.item?.external && props.ite
:rel="item?.external ? 'noopener noreferrer' : null"
class="text-left text-14px w-full flex flex-row items-center justify-between gap-x-8px px-8px py-8px cursor-pointer rounded-md"
:class="{
'text-beta bg-transparent hover:text-white hover:bg-gradient-to-r hover:from-red hover:to-orange focus:text-white focus:bg-gradient-to-r focus:from-red focus:to-orange focus:outline-none': !item?.emphasize,
'text-white bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60': item?.emphasize,
'text-beta bg-transparent hover:text-white hover:bg-gradient-to-r hover:from-unraid-red hover:to-orange focus:text-white focus:bg-gradient-to-r focus:from-unraid-red focus:to-orange focus:outline-none': !item?.emphasize,
'text-white bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60': item?.emphasize,
'group': showExternalIconOnHover,
}"
>

View File

@@ -24,7 +24,7 @@ const showExpireTime = computed(() => {
:is="action.click ? 'button' : 'a'"
@click="action.click()"
rel="noopener noreferrer"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60"
class="text-white text-14px text-center w-full flex-none flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60"
target="_blank"
download
>

View File

@@ -42,8 +42,8 @@ const title = computed((): string => {
class="group text-18px hover:text-alpha focus:text-alpha border border-transparent relative flex flex-row justify-end items-center h-full gap-x-8px outline-none focus:outline-none"
:title="title"
>
<InformationCircleIcon v-if="pluginOutdated" class="text-red fill-current relative w-24px h-24px" />
<ExclamationTriangleIcon v-else-if="showErrorIcon" class="text-red fill-current relative w-24px h-24px" />
<InformationCircleIcon v-if="pluginOutdated" class="text-unraid-red fill-current relative w-24px h-24px" />
<ExclamationTriangleIcon v-else-if="showErrorIcon" class="text-unraid-red fill-current relative w-24px h-24px" />
<span v-if="text" class="leading-none">{{ text }}</span>
<UpcDropdownTriggerMenuIcon :open="dropdownVisible" />
<BrandAvatar />

View File

@@ -1,5 +1,5 @@
<template>
<nav class="flex flex-col gap-y-8px p-8px bg-alpha border rounded-lg shadow-[var(--ring-offset-shadow)_var(--ring-shadow)_var(--shadow-beta)]">
<nav class="flex flex-col gap-y-8px p-8px bg-alpha rounded-lg shadow-[var(--ring-offset-shadow)_var(--ring-shadow)_var(--shadow-beta)]">
<slot/>
</nav>
</template>

View File

@@ -1,3 +1,3 @@
<template>
<hr class="w-full h-2px bg-gradient-to-r from-red to-orange shadow-none border-none rounded" />
<hr class="w-full h-2px bg-gradient-to-r from-unraid-red to-orange shadow-none border-none rounded" />
</template>

View File

@@ -57,7 +57,7 @@ const features = ref<UserProfilePromoFeature[]>([
const staging = ref(false);
const { install } = useInstallPlugin();
const installButtonClasses = 'text-white text-14px text-center w-full flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-red to-orange hover:from-red/60 hover:to-orange/60 focus:from-red/60 focus:to-orange/60';
const installButtonClasses = 'text-white text-14px text-center w-full flex flex-row items-center justify-center gap-x-8px px-8px py-8px cursor-pointer rounded-md bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60';
</script>
<template>

View File

@@ -25,13 +25,13 @@ const upgradeAction = computed((): ServerStateDataAction | undefined => {
</UpcServerStateBuy>
</template>
<h5 v-else>
Unraid OS <em :class="{ 'text-red': stateData.error || state === 'EEXPIRED' }"><strong>{{ stateData.humanReadable }}</strong></em>
Unraid OS <em :class="{ 'text-unraid-red': stateData.error || state === 'EEXPIRED' }"><strong>{{ stateData.humanReadable }}</strong></em>
</h5>
<template v-if="purchaseAction">
<UpcServerStateBuy
@click="purchaseAction.click()"
class="text-orange-dark"
class="text-orange-dark relative top-[1px]"
:title="'Purchase'"
>{{ 'Purchase' }}</UpcServerStateBuy>
</template>

View File

@@ -48,7 +48,7 @@ watch(wanIp, async () => {
<template>
<span v-if="loading" class="italic">{{ 'Checking WAN IPs' }}</span>
<template v-else>
<span v-if="computedError" class="text-red font-semibold">{{ computedError }}</span>
<span v-if="computedError" class="text-unraid-red font-semibold">{{ computedError }}</span>
<template v-else>
<span v-if="isRemoteAccess">{{ `Remark: your WAN IPv4 is ${wanIp}` }}</span>
<span v-else-if="phpWanIp === wanIp && !isRemoteAccess">{{ `Remark: your WAN IPv4 is ${wanIp}` }}</span>

View File

@@ -41,17 +41,31 @@ export const useCallbackActionsStore = defineStore(
console.debug('[actions] DONE');
setTimeout(() => {
callbackLoading.value = false;
}, 2500);
}, 1000);
}
});
};
const closeCallbackFeedback = () => callbackFeedbackVisible.value = false;
const preventClose = (e: { preventDefault: () => void; returnValue: string; }) => {
e.preventDefault();
// eslint-disable-next-line no-param-reassign
e.returnValue = '';
// eslint-disable-next-line no-alert
alert('Closing this pop-up window while actions are being preformed may lead to unintended errors.');
};
watch(callbackLoading, (newVal, _oldVal) => {
console.debug('[callbackLoading]', newVal);
if (newVal === true) {
console.debug('[callbackLoading] true', 'addEventListener');
window.addEventListener('beforeunload', preventClose);
}
// removing query string once actions are done so users can't refresh the page and go through the same actions
if (newVal === false) {
console.debug('[callbackLoading] false', 'removeEventListener');
window.removeEventListener('beforeunload', preventClose);
console.debug('[callbackLoading] push history w/o query');
window.history.pushState(null, '', window.location.pathname);
}

View File

@@ -112,6 +112,7 @@ export const useServerStore = defineStore('server', () => {
flashVendor: flashVendor.value,
guid: guid.value,
keyfile: keyfile.value,
lanIp: lanIp.value,
name: name.value,
registered: registered.value ?? false,
state: state.value,

View File

@@ -21,11 +21,7 @@ export default <Partial<Config>>{
'orange-dark': '#f15a2c',
orange: '#ff8c2f',
red: '#E22828',
yellow: '#F6E05E',
green: '#009900',
blue: '#9089f7',
'unraid-red': '#E22828',
alpha: 'var(--color-alpha)',
beta: 'var(--color-beta)',

View File

@@ -57,6 +57,7 @@ export interface ServerAccountCallbackSendPayload {
flashVendor?: string;
guid?: string;
keyfile?: string;
lanIp?: string;
locale?: string;
name?: string;
registered: boolean;