Agent builder UI.

This commit is contained in:
Haiping Chen 2023-12-21 22:09:01 -06:00
parent ff9df4c4a7
commit 7283259455
215 changed files with 4125 additions and 465 deletions

View file

@ -27,7 +27,7 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
* Support multiple LLM platforms (ChatGPT 3.5 / 4.0, PaLM 2, LLaMA 2, HuggingFace).
* Allow multiple agents with different responsibilities cooperate to complete complex tasks.
* Build, test, evaluate and audit your LLM agent in one place.
* Build-in Web Live Chat UI written in SvelteKit.
* Build-in Agent Builder UI written in SvelteKit.
* Abstract standard Rich Content data structure. Integrate with popular message channels like Facebook Messenger, Slack and Telegram.
* Provide RESTful Open API and WebSocket real-time communication.
@ -39,18 +39,17 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
PS D:\BotSharp\> dotnet run -p .\src\WebStarter
```
2. Run UI project, reference to [Web Live Chat](src/web-live-chat/README.md).
2. Run UI project, reference to [Agent Builder](src/agent-builder/README.md).
```sh
PS D:\> cd .\src\web-live-chat
PS D:\> cd .\src\agent-builder
PS D:\> npm install --force
PS D:\> npm run dev
```
Access http://localhost:5010/chat/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a
![Alt text](./docs/static/screenshots/web-live-chat.png)
Access http://localhost:5015/
<img src="./docs/static/screenshots/agent-builder-agents.png" height="450px"/>
<img src="./docs/static/screenshots/web-live-chat.png" height="450px"/>
### Core Modules

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -39,7 +39,7 @@ builder.Services.AddBotSharpLogger(builder.Configuration);
builder.Services.AddCors(options =>
{
options.AddPolicy("MyCorsPolicy",
builder => builder.WithOrigins("http://localhost:5010")
builder => builder.WithOrigins("http://localhost:5015")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());

View file

@ -1,6 +1,6 @@
[
{
"text": "Hello, I'm an AI assistant that help you do variety of tasks."
"text": "Hello, I'm an AI assistant that help you order a pizza."
},
{
"rich_type": "quick_reply",

View file

@ -3,6 +3,7 @@ node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*

View file

@ -1,3 +1,7 @@
# Agent Builder
The `Agent Builder` is a web app used to manage agents and conversations. Through it you can use it to build new Agents and manage existing Agents.
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
{
"name": "web-live-chat",
"name": "agent-builder",
"version": "0.1.0",
"private": true,
"scripts": {
@ -22,18 +22,35 @@
"prettier-plugin-svelte": "^3.0.0",
"sass": "^1.69.5",
"svelte": "^4.2.8",
"svelte-carousel": "^1.0.25",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
"svelte-range-slider-pips": "^2.2.3",
"vite": "^5.0.0"
},
"type": "module",
"dependencies": {
"@ernane/svelte-star-rating": "^1.1.4",
"@fullcalendar/common": "^5.11.5",
"@microsoft/signalr": "^8.0.0",
"@sveltejs/adapter-static": "^3.0.0",
"@twilio/voice-sdk": "^2.9.0",
"@vincjo/datatables": "^1.12.7",
"apexcharts": "^3.44.2",
"axios": "^1.6.2",
"bootstrap": "^5.3.2",
"chart.js": "^4.4.0",
"fullcalendar": "^6.1.9",
"overlayscrollbars": "^2.4.4",
"overlayscrollbars-svelte": "^0.5.2",
"svelte-awesome-color-picker": "^2.4.7",
"svelte-chartjs": "^3.1.2",
"svelte-file-dropzone": "^2.0.2",
"svelte-flatpickr": "^3.3.3",
"svelte-i18n": "^4.0.0",
"svelte-link": "^1.4.0",
"sveltestrap": "^5.11.2"
"svelte-select": "^5.7.0",
"sveltestrap": "^5.11.2",
"sweetalert2": "^11.6.13",
"swiper": "^10.3.1"
}
}

View file

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" style="overflow: hidden;">
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View file

@ -0,0 +1,25 @@
<script>
import { Row, Col, Breadcrumb, BreadcrumbItem } from 'sveltestrap';
import Link from 'svelte-link';
export let title;
export let pagetitle;
</script>
<Row>
<Col xs="12">
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
<h4 class="mb-sm-0 font-size-18">{pagetitle}</h4>
<div class="page-title-right">
<ol class="breadcrumb m-0">
<BreadcrumbItem>
<Link href="#">{title}</Link>
</BreadcrumbItem>
<BreadcrumbItem active>
{pagetitle}
</BreadcrumbItem>
</ol>
</div>
</div>
</Col>
</Row>

View file

@ -0,0 +1,27 @@
<script context="module">
import { browser } from '$app/environment';
export function getChartColorsArray(colors) {
if (browser) {
if (colors) {
return colors.map(function (value) {
var newValue = value.replace(' ', '');
if (newValue.indexOf(',') === -1) {
var color = getComputedStyle(document.documentElement).getPropertyValue(newValue);
if (color) return color;
else return newValue;
} else {
var val = value.split(',');
if (val.length == 2) {
var rgbaColor = getComputedStyle(document.documentElement).getPropertyValue(val[0]);
rgbaColor = 'rgba(' + rgbaColor + ',' + val[1] + ')';
return rgbaColor;
} else {
return newValue;
}
}
});
}
}
}
</script>

View file

@ -0,0 +1,40 @@
<script>
let isFullScreenMode = true;
import { browser } from '$app/environment';
import Link from 'svelte-link';
function toggleFullscreen() {
if (browser) {
if (
!document.fullscreenElement &&
/* alternative standard method */ !document.mozFullScreenElement &&
!document.webkitFullscreenElement
) {
// current working methods
isFullScreenMode = false;
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
isFullScreenMode = true;
if (document.cancelFullScreen) {
document.cancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
}
}
}
</script>
<div class="dropdown d-none d-lg-inline-block ms-1">
<button on:click={toggleFullscreen} class="btn header-item noti-icon waves-effect">
<i class={isFullScreenMode ? 'bx bx-fullscreen fs-22' : 'bx bx-exit-fullscreen fs-22'} />
</button>
</div>

View file

@ -3,5 +3,5 @@
</script>
<svelte:head>
<title>{title} | Skote - Admin & Dashboard Template</title>
<title>{title} | Agent Builder - Admin & Dashboard</title>
</svelte:head>

View file

@ -0,0 +1,58 @@
<script>
import {
Dropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from "sveltestrap";
import { setupI18n } from "$lib/helpers/i18n";
import languages from "$lib/common/data/languages";
import { onMount } from "svelte";
let selectedLang;
let isOpen = false;
function handleLocaleChange(lang) {
setupI18n({ withLocale: lang });
selectedLang = lang
localStorage.setItem("I18N_LANGUAGE", lang);
}
onMount(() => {
localStorage.getItem("I18N_LANGUAGE") || "en";
})
</script>
<Dropdown {isOpen} toggle={() => (isOpen = !isOpen)} class="d-inline-block">
<DropdownToggle class="btn header-item" tag="button" color="">
<img
src='/images/flags/us.jpg'
alt="Samply"
height="16"
/>
</DropdownToggle>
<DropdownMenu class="language-switch dropdown-menu-end">
{#each languages as language}
<DropdownItem
key={language.value}
on:click={() => handleLocaleChange(language.value)}
class={`notify-item language ${
selectedLang === language.value ? "active" : "none"
}`}
>
<img
src={language.flag}
alt="Samply"
class="me-2"
height="12"
/>
<span class="align-middle">
{language.label}
</span>
</DropdownItem>
{/each}
</DropdownMenu>
</Dropdown>

View file

@ -0,0 +1,121 @@
<script lang="ts">
import Link from 'svelte-link/src/Link.svelte';
import { Dropdown, DropdownToggle, DropdownMenu } from 'sveltestrap';
import "overlayscrollbars/overlayscrollbars.css";
import { OverlayScrollbars } from "overlayscrollbars";
import { onMount } from 'svelte';
const options = {
scrollbars: {
visibility: "auto", // You can adjust the visibility ('auto', 'hidden', 'visible')
autoHide: "move", // You can adjust the auto-hide behavior ('move', 'scroll', false)
autoHideDelay: 100,
dragScroll: true,
clickScroll: false,
theme: "os-theme-light",
pointers: ["mouse", "touch", "pen"],
},
};
onMount(() => {
const menuElement = document.querySelector("#notification");
OverlayScrollbars(menuElement, options);
})
</script>
<Dropdown class="d-none d-lg-inline-block">
<DropdownToggle type="button" color="" tag="a" class="btn header-item noti-icon waves-effect">
<i class="bx bx-bell bx-tada" />
<span class="badge bg-danger rounded-pill">3</span>
</DropdownToggle>
<DropdownMenu class="dropdown-menu-lg" end>
<div class="p-3">
<div class="row align-items-center">
<div class="col">
<h6 class="m-0">Notifications</h6>
</div>
<div class="col-auto">
<Link href="#!" class="small">View All</Link>
</div>
</div>
</div>
<div style="max-height: 230px;" id="notification">
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<div class="avatar-xs me-3">
<span class="avatar-title bg-primary rounded-circle font-size-16">
<i class="bx bx-cart" />
</span>
</div>
<div class="flex-grow-1">
<h6 class="mb-1" >Your order is placed</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >If several languages coalesce the grammar</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >3 min ago</span>
</p>
</div>
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<img
src='/images/users/avatar-3.jpg'
class="me-3 rounded-circle avatar-xs"
alt="user-pic"
/>
<div class="flex-grow-1">
<h6 class="mb-1">James Lemire</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >It will seem like simplified English.</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >1 hours ago</span>
</p>
</div>
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<div class="avatar-xs me-3">
<span class="avatar-title bg-success rounded-circle font-size-16">
<i class="bx bx-badge-check" />
</span>
</div>
<div class="flex-grow-1">
<h6 class="mb-1" >Your item is shipped</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >If several languages coalesce the grammar</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >3 min ago</span>
</p>
</div>
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<img
src='/images/users/avatar-4.jpg'
class="me-3 rounded-circle avatar-xs"
alt="user-pic"
/>
<div class="flex-grow-1">
<h6 class="mb-1">Salena Layfield</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >
As a skeptical Cambridge friend of mine occidental.
</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >1 hours ago</span>
</p>
</div>
</div>
</div>
</Link>
</div>
</DropdownMenu>
</Dropdown>

View file

@ -0,0 +1,55 @@
<script>
import { onMount } from 'svelte';
import Link from 'svelte-link';
/** @type {import('$lib/types').Pagination} */
export let pagination;
/** @type {number} */
$: totalPages = Math.ceil(pagination.count / pagination.size);
/** @type {number} */
$: offset = pagination.page * pagination.size;
/** @type {number[]} */
$: pages = Array.from(String(totalPages), Number);
onMount(async () => {
});
</script>
<div class="row justify-content-between align-items-center">
<div class="col-auto me-auto">
<p class="text-muted mb-0">Showing <b>{offset}</b> to <b>{offset + pagination.size}</b> of <b>{pagination.count}</b> entries</p>
</div>
<div class="col-auto">
<div class="card d-inline-block ms-auto mb-0">
<div class="card-body p-2">
<nav aria-label="Page navigation example" class="mb-0">
<ul class="pagination mb-0">
<li class="page-item">
<Link class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</Link>
</li>
{#each pages as page}
{#if page == pagination.page + 1}
<li class="page-item active"><Link class="page-link" href="#">{page}</Link></li>
{:else}
<li class="page-item"><Link class="page-link" href="#">{page}</Link></li>
{/if}
{/each}
<li class="page-item">
<Link class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</Link>
</li>
</ul>
</nav>
</div>
</div>
</div>
<!--end col-->
</div>

View file

@ -0,0 +1,51 @@
<script>
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'sveltestrap';
import { goto } from '$app/navigation';
import { browser } from '$app/environment';
function logout() {
if (browser){
localStorage.removeItem('authUser');
}
goto('/login');
};
</script>
<Dropdown class="d-inline-block">
<DropdownToggle
tag="a"
color=""
class="btn header-item waves-effect"
id="page-header-user-dropdown"
>
<img class="rounded-circle header-profile-user" src='/images/users/user-dummy.jpg' alt="Header Avatar" />
<span class="d-none d-xl-inline-block ms-1" key="t-henry">Henry</span>
<i class="mdi mdi-chevron-down d-none d-xl-inline-block" />
</DropdownToggle>
<DropdownMenu end>
<!-- item-->
<DropdownItem href="#"
><i class="bx bx-user font-size-16 align-middle me-1" />
<span>Profile</span>
</DropdownItem>
<DropdownItem href="#"
><i class="bx bx-wallet font-size-16 align-middle me-1" />
<span>My Wallet</span>
</DropdownItem>
<DropdownItem href="#"
><span class="badge bg-success float-end">11</span><i
class="bx bx-wrench font-size-16 align-middle me-1"
/> <span key="t-settings">Settings</span>
</DropdownItem>
<DropdownItem href="#">
<i class="bx bx-lock-open font-size-16 align-middle me-1" />
<span key="t-lock-screen">Lock screen</span>
</DropdownItem>
<DropdownItem divider />
<DropdownItem href="#" >
<div on:click={logout}>
<i class="bx bx-power-off font-size-16 align-middle me-1 text-danger" /> <span>Logout</span>
</div>
</DropdownItem>
</DropdownMenu>
</Dropdown>

View file

@ -0,0 +1,321 @@
<script>
import Link from 'svelte-link';
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';
import { onMount } from 'svelte';
export let sidebarColor = 'dark';
export let topbarColor = 'light';
export let layoutWidth = 'fluid';
export let layoutMode = 'light';
export let sidebarSize = 'icon';
export let closebar;
const options = {
scrollbars: {
visibility: 'auto', // You can adjust the visibility ('auto', 'hidden', 'visible')
autoHide: 'move', // You can adjust the auto-hide behavior ('move', 'scroll', false)
autoHideDelay: 100,
dragScroll: true,
clickScroll: false,
theme: 'os-theme-dark',
pointers: ['mouse', 'touch', 'pen']
}
};
function changeBodyAttribute(attribute, value) {
if (document.body) document.body.setAttribute(attribute, value);
if(attribute == "data-sidebar-size"){
if(value == "icon"){
document.body.classList.add('vertical-collpsed');
}else{
document.body.classList.remove('vertical-collpsed');
}
if (document.body.classList.contains('vertical-collpsed')) {
if (document.querySelector('#vertical-menu')) {
const Instance = OverlayScrollbars(document.querySelector('#vertical-menu'));
if (Instance) {
Instance.destroy();
}
}
} else {
const options = {
scrollbars: {
visibility: 'auto',
autoHide: 'move',
autoHideDelay: 100,
dragScroll: true,
clickScroll: false,
theme: 'os-theme-light',
pointers: ['mouse', 'touch', 'pen']
}
};
const menuElement = document.querySelector('#vertical-menu');
if (menuElement) {
OverlayScrollbars(menuElement, options);
}
}
}
}
function changeLayoutMode(attribute, value) {
if (document.documentElement) document.documentElement.setAttribute(attribute, value);
}
function changeLayoutwidth(attribute, value) {
if (document.body) document.body.setAttribute(attribute, value);
if (value == 'boxed') {
document.body.classList.add('vertical-collpsed');
} else {
document.body.classList.remove('vertical-collpsed');
}
if (document.body.classList.contains('vertical-collpsed')) {
if (document.querySelector('#vertical-menu')) {
const Instance = OverlayScrollbars(document.querySelector('#vertical-menu'));
if (Instance) {
Instance.destroy();
}
}
} else {
const options = {
scrollbars: {
visibility: 'auto',
autoHide: 'move',
autoHideDelay: 100,
dragScroll: true,
clickScroll: false,
theme: 'os-theme-light',
pointers: ['mouse', 'touch', 'pen']
}
};
const menuElement = document.querySelector('#vertical-menu');
if (menuElement) {
OverlayScrollbars(menuElement, options);
}
}
}
onMount(() => {
const menuElement = document.querySelector('#right-bar');
OverlayScrollbars(menuElement, options);
changeBodyAttribute('data-sidebar', sidebarColor);
changeBodyAttribute('data-topbar', topbarColor);
changeBodyAttribute('data-sidebar-size', sidebarSize);
changeLayoutwidth('data-layout-size', layoutWidth);
changeLayoutMode('data-bs-theme', layoutMode);
setTimeout(() => {
if (document.body.getAttribute('data-layout') == 'horizontal') {
document.getElementById('sidebaroption').style.display = 'none';
} else {
document.getElementById('sidebaroption').style.display = 'block';
}
}, 500);
});
</script>
<div class="right-bar">
<div class="h-100" id="right-bar">
<div class="rightbar-title d-flex align-items-center px-3 py-4">
<h5 class="m-0 me-2">Settings</h5>
<Link href="#" class="right-bar-toggle ms-auto" on:click={closebar}>
<i class="mdi mdi-close noti-icon" />
</Link>
</div>
<!-- Sidebar Color -->
<div class="p-4" id="sidebaroption">
<h6 class="mb-3">Sidebar Color</h6>
<hr class="mt-0" />
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-color"
id="sidebar-color-light"
checked={sidebarColor == 'light'}
on:change={() => changeBodyAttribute('data-sidebar', 'light')}
/>
<label class="form-check-label" for="sidebar-color-light">Light</label>
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-color"
id="sidebar-color-dark"
checked={sidebarColor == 'dark'}
on:change={() => changeBodyAttribute('data-sidebar', 'dark')}
/>
<label class="form-check-label" for="sidebar-color-dark">Dark</label>
</div>
<div class="form-check form-switch">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-color"
id="sidebar-color-colored"
checked={sidebarColor == 'colored'}
on:change={() => changeBodyAttribute('data-sidebar', 'colored')}
/>
<label class="form-check-label" for="sidebar-color-colored">Colored</label>
</div>
</div>
<!-- Sidebar Size -->
<div class="p-4" id="sidebarsizeoption">
<h6 class="mb-3">Sidebar Size</h6>
<hr class="mt-0" />
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-size"
id="sidebar-size-light"
checked={sidebarSize == 'fluid'}
on:change={() => changeBodyAttribute('data-sidebar-size', 'fluid')}
/>
<label class="form-check-label" for="sidebar-size-fluid">Fluid</label>
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-size"
id="sidebar-size-small"
checked={sidebarSize == 'small'}
on:change={() => changeBodyAttribute('data-sidebar-size', 'small')}
/>
<label class="form-check-label" for="sidebar-size-small">Compact</label>
</div>
<div class="form-check form-switch">
<input
class="form-check-input theme-choice"
type="radio"
name="sidebar-size"
id="sidebar-size-icon"
checked={sidebarSize == 'icon'}
on:change={() => changeBodyAttribute('data-sidebar-size', 'icon')}
/>
<label class="form-check-label" for="sidebar-size-icon">Icon</label>
</div>
</div>
<!-- Topbar Theme -->
<div class="p-4">
<h6 class=" mb-3">Topbar Theme</h6>
<hr class="mt-0" />
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="topbar-color"
id="topbar-color-light"
checked={topbarColor == 'light'}
on:change={() => changeBodyAttribute('data-topbar', 'light')}
/>
<label class="form-check-label" for="topbar-color-light">Light</label>
</div>
<div class="form-check form-switch">
<input
class="form-check-input theme-choice"
type="radio"
name="topbar-color"
id="topbar-color-dark"
checked={topbarColor == 'dark'}
on:change={() => changeBodyAttribute('data-topbar', 'dark')}
/>
<label class="form-check-label" for="topbar-color-dark">Dark</label>
</div>
</div>
<!-- Layout Width -->
<div class="p-4">
<h6 class=" mb-3">Layout Width</h6>
<hr class="mt-0" />
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="layout-width"
id="layout-width-fluid"
checked={layoutWidth == 'fluid'}
on:change={() => changeLayoutwidth('data-layout-size', 'fluid')}
/>
<label class="form-check-label" for="layout-width-fluid">Fluid</label>
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="layout-width"
id="layout-width-boxed"
checked={layoutWidth == 'boxed'}
on:change={() => changeLayoutwidth('data-layout-size', 'boxed')}
/>
<label class="form-check-label" for="layout-width-boxed">Boxed</label>
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="layout-width"
id="layout-width-boxed"
checked={layoutWidth == 'scrollable'}
on:change={() => changeLayoutwidth('data-layout-scrollable', 'true')}
/>
<label class="form-check-label" for="layout-width-scrollable">Scrollable</label>
</div>
</div>
<!-- Settings -->
<hr class="mt-0" />
<h6 class="text-center mb-0">Choose Layouts</h6>
<div class="p-4">
<div class="mb-2">
<img src='/images/layouts/layout-1.jpg' class="img-thumbnail" alt="layout images" />
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="layout-mode"
id="layout-mode-light"
checked={layoutMode == 'light'}
on:change={() => changeLayoutMode('data-bs-theme', 'light')}
/>
<label class="form-check-label" for="layout-mode-light">Light</label>
</div>
<div class="mb-2">
<img src='/images/layouts/layout-2.jpg' class="img-thumbnail" alt="layout images" />
</div>
<div class="form-check form-switch mb-3">
<input
class="form-check-input theme-choice"
type="radio"
name="layout-mode"
id="layout-mode-dark"
checked={layoutMode == 'dark'}
on:change={() => changeLayoutMode('data-bs-theme', 'dark')}
/>
<label class="form-check-label" for="layout-mode-dark">Dark</label>
</div>
</div>
</div>
<!-- end slimscroll-menu-->
</div>
<!-- /Right-bar -->
<!-- Right bar overlay-->
<div class="rightbar-overlay" on:click={closebar} />

View file

@ -0,0 +1,31 @@
const Navdata = [
{
label: 'Agent',
isHeader: true
},
{
"icon": "bx bx-bot",
"label": "Agents",
"link": "/agent"
},
{
label: 'Conversation',
isHeader: true
},
{
"icon": "bx bx-conversation",
"label": "Conversation",
"link": "/conversation"
},
{
"icon": "bx bx-message-dots",
"label": "Live Chat",
"link": "/chat"
}
]
const MOCK_DATA = {
Navdata
}
export default MOCK_DATA;

View file

@ -0,0 +1,14 @@
const languages = [
{
label: "English",
flag: '/images/flags/us.jpg',
value: 'en'
},
{
label: "Chinese",
flag: '/images/flags/china.png',
value: 'zh'
},
]
export default languages;

View file

@ -0,0 +1,38 @@
<script>
import Link from 'svelte-link';
import { Col, Container, Row } from 'sveltestrap';
import HeadTitle from '$lib/common/HeadTitle.svelte';
</script>
<HeadTitle title="500 Error Page" />
<div class="account-pages my-5 pt-5">
<Container>
<Row>
<Col lg="12">
<div class="text-center mb-5">
<h1 class="display-2 fw-medium">
5
<i class="bx bx-buoy bx-spin text-primary display-3" />
0
</h1>
<h4 class="text-uppercase">Internal Server Error</h4>
<div class="mt-5 text-center">
<Link class="btn btn-primary" href="/dashboard">
Back to Dashboard
</Link>
</div>
</div>
</Col>
</Row>
<Row class="justify-content-center">
<Col md="8" xl="6">
<div>
<img src='/images/error-img.png' alt="" class="img-fluid" />
</div>
</Col>
</Row>
</Container>
</div>

View file

@ -0,0 +1,21 @@
import { dictionary, locale, _} from 'svelte-i18n';
const MESSAGE_FILE_URL_TEMPLATE = '/src/lang/{locale}.json';
let cachedLocale;
function setupI18n({ withLocale: _locale } = { withLocale: 'en' }) {
const messsagesFileUrl = MESSAGE_FILE_URL_TEMPLATE.replace('{locale}', _locale);
return fetch(messsagesFileUrl)
.then(response => response.json())
.then((messages) => {
dictionary.set({ [_locale]: messages });
cachedLocale = _locale;
locale.set(_locale);
});
}
export { _, locale, setupI18n };

View file

@ -6,6 +6,22 @@
* @property {string} full_name - The user full name.
* @property {string} email - The user email.
* @property {string} role - The user role.
* @property {string} avatar - The user avatar.
* @property {string} color
*/
/**
* @typedef {Object} Pagination
* @property {number} page - The plugin full name.
* @property {number} size - The plugin name.
* @property {number} count - Row count.
*/
/**
* @template T
* @typedef {Object} PagedItems<T>
* @property {number} count - Row count.
* @property {T[]} items - Items.
*/
/**
@ -29,12 +45,22 @@
* @property {AgentWelcomeInfo} welcome_info - Welcome information.
*/
/**
* @typedef {Object} ConversationFilter
* @property {Pagination} pager - Pagination
* @property {string?} agentId - The agent id.
* @property {string?} channel - The conversation channel.
* @property {string?} status - The conversation status.
*/
/**
* @typedef {Object} ConversationModel
* @property {string} id - The conversation id.
* @property {string} title - The conversation title.
* @property {UserModel} user - The conversation initializer.
* @property {string} agent_id - The conversation agent id.
* @property {string} channel - The conversation status.
* @property {string} status - The conversation status.
* @property {number} unread_msg_count - The unread message count.
* @property {Date} updated_time - The conversation updated time.
* @property {Date} created_time - The conversation created time.
@ -125,7 +151,6 @@ IRichContent.prototype.text;
* @param {string} text
*/
// having to export an empty object here is annoying,
// but required for vscode to pass on your types.
export default {};

View file

@ -0,0 +1,183 @@
{
"title": "Agent Builder - Admin & Dashboard",
"Menu": "Menu",
"Dashboards": "Dashboards",
"Default": "Default",
"Saas": "Saas",
"Crypto": "Crypto",
"Blog": "Blog",
"Jobs": "Jobs",
"Layouts": "Layouts",
"Horizontal": "Horizontal",
"Light Sidebar": "Light Sidebar",
"Compact Sidebar": "Compact Sidebar",
"Icon Sidebar": "Icon Sidebar",
"Boxed Layout": "Boxed Layout",
"Preloader": "Preloader",
"Colored Sidebar": "Colored Sidebar",
"Scrollable": "Scrollable",
"Apps": "Apps",
"TUI-Calendar": "TUI-Calendar",
"Full-Calendario": "Full-Calendario",
"Chat": "Chat",
"File Manager": "File Manager",
"New": "New",
"Hot": "Hot",
"Ecommerce": "Ecommerce",
"Products": "Products",
"Product Detail": "Product Detail",
"Orders": "Orders",
"Customers": "Customers",
"Cart": "Cart",
"Checkout": "Checkout",
"Shops": "Shops",
"Add Product": "Add Product",
"Wallet": "Wallet",
"Buy / Sell": "Buy / Sell",
"Exchange": "Exchange",
"Lending": "Lending",
"KYC Application": "KYC Application",
"ICO Landing": "ICO Landing",
"E-mail": "E-mail",
"Inbox": "Inbox",
"Read Email": "Read Email",
"Templates": "Templates",
"Basic Action": "Basic Action",
"Alert Email": "Alert Email",
"Billing Email": "Billing Email",
"Invoices": "Invoices",
"Invoice List": "Invoice List",
"Invoice Detail": "Invoice Detail",
"Projects": "Projects",
"Projects Grid": "Projects Grid",
"Projects List": "Projects List",
"Project Overview": "Project Overview",
"Create New": "Create New",
"Tasks": "Tasks",
"Task List": "Task List",
"Kanban Board": "Kanban Board",
"Create Task": "Create Task",
"Contacts": "Contacts",
"User Grid": "User Grid",
"User List": "User List",
"Edit Details": "Edit Details",
"Profile": "Profile",
"Blog List": "Blog List",
"Blog Grid": "Blog Grid",
"Blog Details": "Blog Details",
"Conversation List": "Conversation List",
"Job Grid": "Job Grid",
"Apply Job": "Apply Job",
"Job Details": "Job Details",
"Jobs Categories": "Jobs Categories",
"Candidate": "Candidate",
"List": "List",
"Overview": "Overview",
"Pages": "Pages",
"Authentication": "Authentication",
"Login": "Login",
"Login 2": "Login 2",
"Register": "Register",
"Register 2": "Register 2",
"Recover Password": "Recover Password",
"Recover Password 2": "Recover Password 2",
"Lock screen": "Lock screen",
"Lock screen 2": "Lock screen 2",
"Confirm Mail": "Confirm Mail",
"Confirm Mail 2": "Confirm Mail 2",
"Email Verification": "Email Verification",
"Email Verification 2": "Email Verification 2",
"Two Step Verification": "Two Step Verification",
"Two Step Verification 2": "Two Step Verification 2",
"Utility": "Utility",
"Starter Page": "Starter Page",
"Maintenance": "Maintenance",
"Coming Soon": "Coming Soon",
"Timeline": "Timeline",
"FAQs": "FAQs",
"Pricing": "Pricing",
"Error 404": "Error 404",
"Error 500": "Error 500",
"Components": "Components",
"UI Elements": "UI Elements",
"Alerts": "Alerts",
"Buttons": "Buttons",
"Cards": "Cards",
"Carousel": "Carousel",
"Dropdowns": "Dropdowns",
"Grid": "Grid",
"Images": "Images",
"Lightbox": "Lightbox",
"Modals": "Modals",
"Offcanvas": "Offcanvas",
"Range Slider": "Range Slider",
"Session Timeout": "Session Timeout",
"Progress Bars": "Progress Bars",
"Sweet-Alert": "Sweet-Alert",
"Tabs & Accordions": "Tabs & Accordions",
"Typography": "Typography",
"Video": "Video",
"General": "General",
"Colors": "Colors",
"Utilities": "Utilities",
"Rating": "Rating",
"Notifications": "Notifications",
"Image Cropper": "Image Cropper",
"Forms": "Forms",
"Forms Elements": "Forms Elements",
"Forms Layouts": "Forms Layouts",
"Forms Validation": "Forms Validation",
"Forms Advanced": "Forms Advanced",
"Forms Editors": "Forms Editors",
"Forms File Upload": "Forms File Upload",
"Form Xeditable": "Form Xeditable",
"Form Repeater": "Form Repeater",
"Form Wizard": "Form Wizard",
"Form Mask": "Form Mask",
"Tables": "Tables",
"Basic Tables": "Basic Tables",
"Data Tables": "Data Tables",
"Responsive Table": "Responsive Table",
"Editable Table": "Editable Table",
"Charts": "Charts",
"Apex Charts": "Apex Charts",
"E Charts": "E Charts",
"Chartjs Charts": "Chartjs Charts",
"Flot Charts": "Flot Charts",
"Toast UI Charts": "Toast UI Charts",
"Jquery Knob Charts": "Jquery Knob Charts",
"Sparkline Charts": "Sparkline Charts",
"Icons": "Icons",
"Boxicons": "Boxicons",
"Material Design": "Material Design",
"Dripicons": "Dripicons",
"Font Awesome": "Font Awesome",
"Maps": "Maps",
"Google maps": "Google maps",
"Vector Maps": "Vector Maps",
"Leaflet Maps": "Leaflet Maps",
"Multi Level": "Multi Level",
"Level 1.1": "Level 1.1",
"Level 1.2": "Level 1.2",
"Level 2.1": "Level 2.1",
"Level 2.2": "Level 2.2",
"Extra Pages": "Extra Pages",
"Vertical": "Vertical",
"Topbar Light": "Topbar Light",
"Colored Topbar": "Colored Topbar",
"Mega Menu": "Mega Menu",
"UI Components": "UI Components",
"Applications": "Applications",
"View all": "View all",
"Your order is placed": "Your order is placed",
"If several languages coalesce the grammar": "If several languages coalesce the grammar",
"3 min ago": "3 min ago",
"It will seem like simplified English": "It will seem like simplified English",
"Your item is shipped": "Your item is shipped",
"As a skeptical Cambridge friend of mine occidental": "As a skeptical Cambridge friend of mine occidental",
"1 hours ago": "1 hours ago",
"View More": "View More",
"My Wallet": "My Wallet",
"Settings": "Settings",
"Logout": "Logout"
}

View file

@ -0,0 +1,365 @@
{
"navbar": {
"search": {
"text": "搜索..."
},
"dropdown": {
"megamenu": {
"text": "超级菜单",
"uicontent": {
"title": "UI组件",
"list": {
"lightbox": "灯箱",
"rangeslider": "范围滑块",
"sweetalert": "甜蜜警报",
"rating": "评分",
"forms": "形式",
"tables": "桌子",
"charts": "图表"
}
},
"application": {
"title": "应用领域",
"list": {
"ecommerce": "电子商务",
"calendar": "日历",
"email": "电子邮件",
"projects": "专案",
"tasks": "任务",
"contacts": "联络人"
}
},
"extrapages": {
"title": "额外页面",
"list": {
"lightsidebar": "侧边灯",
"compactsidebar": "紧凑型侧边栏",
"horizontallayout": "水平布局",
"maintenance": "保养",
"comingsoon": "快来了",
"timeline": "时间线",
"faqs": "常见问题"
}
}
},
"site": {
"list": {
"github": "的GitHub",
"bitbucket": "比特桶",
"dribbble": "运球",
"dropbox": "投寄箱",
"mailchimp": "邮件黑猩猩",
"slack": "松弛"
}
},
"notification": {
"badge": "3",
"text": "通知事项",
"subtext": "查看全部",
"order": {
"title": "您的订单已下达",
"text": "如果几种语言合并了语法",
"time": "3分钟前"
},
"james": {
"title": "詹姆斯·勒米尔",
"text": "好像是简体英语。",
"time": "1小时前"
},
"item": {
"title": "您的物品已发货",
"text": "如果几种语言合并了语法",
"time": "3分钟前"
},
"salena": {
"title": "萨莱娜·莱菲尔德",
"text": "作为西方的一个怀疑的剑桥朋友。",
"time": "1小时前"
},
"button": "装载更多.."
},
"henry": {
"text": "亨利",
"list": {
"profile": "轮廓",
"mywallet": "我的钱包",
"settings": "设定值",
"lockscreen": "锁屏",
"logout": "登出"
}
}
}
},
"menuitems": {
"menu": {
"text": "菜单"
},
"dashboards": {
"text": "仪表板",
"badge": "04",
"list": {
"default": "默认",
"saas": "萨斯",
"crypto": "加密货币",
"blog": "博客",
"jobs":"工作"
}
},
"layouts": {
"text": "版面",
"list": {
"horizontal": "卧式",
"lightsidebar": "侧边灯",
"compactsidebar": "紧凑型侧边栏",
"iconsidebar": "图标侧栏",
"boxed": "盒装版式",
"coloredsidebar": "彩色边栏",
"vertical": "垂直",
"lighttopbar": "轻顶杆",
"coloredheader": "彩色标题"
}
},
"apps": {
"text": "应用"
},
"calendar": {
"text": "日历"
},
"chat": {
"text": "聊天室",
"badge": "新"
},
"filemanager": {
"text": "文件管理器",
"badge": "新"
},
"ecommerce": {
"text": "电子商务",
"list": {
"products": "产品展示",
"productdetail": "产品明细",
"orders": "订单",
"customers": "顾客",
"cart": "大车",
"checkout": "查看",
"shops": "商店",
"addproduct": "添加产品"
}
},
"crypto": {
"text": "加密货币",
"list": {
"wallet": "钱包",
"buy/sell": "买卖",
"exchange": "交换",
"lending": "借贷",
"orders": "订单",
"kycapplication": "KYC应用",
"icolanding": "ICO登陆"
}
},
"email": {
"text": "电子邮件",
"list": {
"inbox": "收件箱",
"reademail": "阅读电子邮件",
"template": {
"text": "范本",
"list": {
"basic": "基本动作",
"alert": "警报电子邮件",
"billing": "帐单电邮"
}
}
}
},
"invoices": {
"text": "发票",
"list": {
"invoicelist": "发票清单",
"invoicedetail": "发票明细"
}
},
"projects": {
"text": "专案",
"list": {
"grid": "项目网格",
"projectlist": "项目清单",
"overview": "项目概况",
"create": "创建新的"
}
},
"tasks": {
"text": "任务",
"list": {
"tasklist": "任务列表",
"kanban": "看板委员会",
"createtask": "创建任务"
}
},
"contacts": {
"text": "联络人",
"list": {
"usergrid": "用户网格",
"userlist": "用户清单",
"profile": "轮廓"
}
},
"blog": {
"text": "博客",
"badge": "新",
"list": {
"bloglist": "博客列表",
"grid": "博客网格",
"detail": "博客详细信息"
}
},
"jobs" : {
"text": "工作",
"list": {
"joblist" : "工作清單",
"jobgrid" : "工作網格",
"applyjob" : "申請工作",
"jobdetails" : "工作詳情",
"jobcategories" : "工作類別",
"candidate" : {
"text": "候選人",
"list": {
"list" : "列表",
"overview" : "概述"
}
}
}
},
"pages": {
"text": "页数"
},
"authentication": {
"text": "认证方式",
"badge": "新",
"list": {
"login": "登录",
"register": "寄存器",
"recoverpwd": "恢复密码",
"lockscreen": "锁屏",
"login-2": "登录2",
"register-2": "注册2",
"recoverpwd-2": "找回密码2",
"lockscreen-2": "锁屏2",
"confirm-mail": "确认邮件",
"confirm-mail-2": "确认邮件2",
"verification": "电子邮件验证",
"verification-2": "电子邮件验证2",
"verification-step": "两步验证",
"verification-step-2": "两步验证2"
}
},
"utility": {
"text": "效用",
"list": {
"starter": "起始页",
"maintenance": "保养",
"timeline": "时间线",
"faqs": "常见问题",
"pricing": "价钱",
"error404": "错误404",
"error500": "错误500",
"comingsoon": "快来了"
}
},
"components": {
"text": "组件"
},
"uielements": {
"text": "UI元素",
"list": {
"alerts": "警报",
"buttons": "纽扣",
"cards": "牌",
"carousel": "轮播",
"dropdowns": "下拉菜单",
"offcanvas": "画布",
"grid": "格网",
"images": "图片",
"modals": "模态",
"rangeslider": "范围滑块",
"session-timeout": "会话超时",
"placeholders": "占位符",
"progressbar": "进度条",
"sweetalert": "甜蜜警报",
"tabs": "标签和手风琴",
"typography": "版式",
"video": "视频",
"general": "一般",
"colors": "色彩",
"lightbox": "灯箱",
"cropper": "圖像裁剪器",
"drawer": "抽屉",
"toast":"吐司",
"utility":"效用"
}
},
"forms": {
"text": "形式",
"badge": "8",
"list": {
"elements": "表单元素",
"layouts": "表单布局",
"validation": "表格验证",
"advanced": "表格高级",
"editor": "表格编辑器",
"fileupload": "表格文件上传",
"repeater": "表单中继器",
"wizard": "表单向导",
"mask": "表格蒙版"
}
},
"tables": {
"text": "桌子",
"list": {
"basic": "基本表",
"datatable": "数据表",
"editabletable": "可编辑表格"
}
},
"charts": {
"text": "图表",
"list": {
"apex": "顶点图",
"chartjs": "图表",
"chartist": "宪章图",
"echart": "电子图表"
}
},
"icons": {
"text": "图示",
"list": {
"boxicons": "盒子图标",
"materialdesign": "材料设计",
"dripicons": "滴灌",
"fontawesome": "字体很棒"
}
},
"maps": {
"text": "地图",
"list": {
"googlemap": "谷歌地图",
"leafletmap": "傳單地圖"
}
},
"multilevel": {
"text": "多层次",
"list": {
"level1": {
"1": "1.1级",
"2": "1.2级",
"level2": {
"1": "2.1级",
"2": "2.2级"
}
}
}
}
}
}

View file

@ -72,8 +72,18 @@ File: Main Css File
// Pages
@import "custom/pages/authentication";
@import "custom/pages/ecommerce";
@import "custom/pages/email";
@import "custom/pages/file-manager";
@import "custom/pages/chat";
@import "custom/pages/projects";
@import "custom/pages/contacts";
@import "custom/pages/crypto";
@import "custom/pages/coming-soon";
@import "custom/pages/timeline";
@import "custom/pages/extras-pages";
@import "custom/pages/jobs";
//RTL
// @import "custom/rtl/bootstrap-rtl";
@ -86,11 +96,6 @@ File: Main Css File
// @import "custom/rtl/structure-rtl";
// @import "custom/rtl/text-rtl";
body {
height: 100vh;
min-height: 100vh;
}
// custom css
.tab-content .nav-tabs {
display: none;

View file

@ -56,7 +56,7 @@
}
.bg-overlay{
background: url("/images/bg-auth-overlay.png");
background: url("../images/bg-auth-overlay.png");
background-size: cover;
background-repeat: no-repeat;
background-position: center;

View file

@ -128,12 +128,12 @@
}
}
.conversation-list {
margin-bottom: 8px;
margin-bottom: 24px;
display: inline-block;
position: relative;
.ctext-wrap {
padding: 8px 10px;
padding: 12px 24px;
background-color: rgba($primary, 0.1);
border-radius: 8px 8px 8px 0px;
overflow: hidden;

View file

@ -0,0 +1,20 @@
//
// coming-soon.scss
//
.counter-number {
font-size: 32px;
font-weight: $font-weight-semibold;
text-align: center;
display: flex;
span {
font-size: 16px;
font-weight: $font-weight-normal;
display: block;
padding-top: 5px;
}
}
.coming-box {
width: 25%;
}

View file

@ -0,0 +1,355 @@
//
// crypto.scss
//
@media (min-width: 576px) {
.currency-value {
position: relative;
&:after {
content: "\F04E1";
font-family: "Material Design Icons";
font-size: 24px;
position: absolute;
width: 45px;
height: 45px;
line-height: 45px;
border-radius: 50%;
text-align: center;
right: 0;
top: 50%;
transform: translateY(-50%);
background-color: $primary;
color: $white;
z-index: 9;
right: -34px;
}
}
}
.crypto-buy-sell-nav-content {
border: 2px solid var(--#{$prefix}border-color);
border-top: 0;
}
// KYC Application
.kyc-doc-verification {
.dropzone {
min-height: 180px;
.dz-message {
margin: 24px 0px;
}
}
}
/******************
Ico Landing
*******************/
.section {
position: relative;
padding-top: 80px;
padding-bottom: 80px;
&.bg-white {
background-color: var(--#{$prefix}secondary-bg) !important;
}
}
.small-title {
color: var(--#{$prefix}secondary-color);
margin-bottom: 8px;
}
// Navigation
.navigation {
padding: 0 16px;
width: 100%;
z-index: 999;
margin-bottom: 0px;
transition: all 0.5s ease-in-out;
border-bottom: 1px solid rgba($white, 0.1);
@media (max-width: 991.98px) {
background-color: var(--#{$prefix}topnav-bg);
}
.navbar-logo {
line-height: 70px;
transition: all 0.4s;
.logo-dark {
display: none;
@media (max-width: 991.98px) {
display: block;
}
}
.logo-light {
display: block;
@media (max-width: 991.98px) {
display: none;
}
}
}
.navbar-nav {
.nav-item {
.nav-link {
color: rgba($white, 0.6);
line-height: 58px;
padding: 6px 16px;
font-weight: $font-weight-medium;
transition: all 0.4s;
@media (max-width: 991.98px) {
color: var(--#{$prefix}header-item-color);
}
&:hover,
&.active {
color: rgba($white, 0.9);
@media (max-width: 991.98px) {
color: $primary;
}
}
@media (max-width: 991.98px) {
line-height: 28px !important;
}
}
}
}
&.nav-sticky {
background-color: var(--#{$prefix}topnav-bg);
box-shadow: $box-shadow;
.navbar-logo {
line-height: 60px;
.logo-dark {
display: var(--#{$prefix}display-block);
}
.logo-light {
display: var(--#{$prefix}display-none);
}
}
.navbar-nav {
.nav-item {
.nav-link {
line-height: 48px;
color: var(--#{$prefix}header-item-color);
&:hover,
&.active {
color: $primary;
}
}
}
}
}
}
.bg-overlay {
position: absolute;
height: 100%;
width: 100%;
right: 0;
bottom: 0;
left: 0;
top: 0;
opacity: 0.7;
background-color: $black;
}
.hero-section {
padding-top: 220px;
padding-bottom: 190px;
&.bg-ico-hero {
background-image: url("../images/crypto/bg-ico-hero.jpg");
background-size: cover;
background-position: top;
}
@media (max-width: 575.98px) {
padding-top: 140px;
padding-bottom: 80px;
}
.hero-title {
font-size: 42px;
@media (max-width: 575.98px) {
font-size: 26px;
}
}
.ico-countdown {
font-size: 22px;
margin-right: -12px;
margin-left: -12px;
@media (max-width: 575.98px) {
display: block;
}
.coming-box {
margin-right: 12px;
margin-left: 12px;
border: 1px solid var(--#{$prefix}border-color);
border-radius: 4px;
padding: 8px;
background-color: var(--#{$prefix}secondary-bg);
@media (max-width: 575.98px) {
display: inline-block;
width: 40%;
margin-bottom: 24px;
}
span {
background-color: var(--#{$prefix}light);
font-size: 12px;
padding: 4px;
margin-top: 8px;
}
}
}
.softcap-progress {
overflow: visible;
.progress-bar {
overflow: visible;
}
.progress-label {
position: relative;
text-align: right;
color: var(--#{$prefix}body-color);
bottom: 20px;
font-size: 12px;
font-weight: $font-weight-medium;
}
}
}
// currency price
.currency-price {
position: relative;
bottom: 40px;
}
// Clients
.client-images {
img {
max-height: 34px;
width: auto !important;
margin: 12px auto;
opacity: 0.7;
transition: all 0.4s;
}
}
// Features
.features-number {
opacity: 0.1;
}
// Team
.team-box {
.team-social-links {
a {
color: var(--#{$prefix}body-color);
font-size: 14px;
}
}
}
// Blog
.blog-box {
.blog-badge {
position: absolute;
top: 12px;
right: 12px;
}
}
// landing footer
.landing-footer {
padding: 80px 0 40px;
background-color: $sidebar-dark-bg;
color: rgba($white, 0.5);
.footer-list-title {
color: rgba($white, 0.9);
}
.footer-list-menu {
li {
a {
display: block;
color: rgba($white, 0.5);
margin-bottom: 14px;
transition: all 0.4s;
&:hover {
color: rgba($white, 0.8);
}
}
}
}
.blog-post {
.post {
display: block;
color: rgba($white, 0.5);
padding: 16px 0px;
border-bottom: 1px solid rgba($white, 0.1);
.post-title {
color: rgba($white, 0.8);
font-size: 14px;
}
&:first-of-type {
padding-top: 0;
}
&:last-of-type {
padding-bottom: 0;
border-bottom: 0;
}
}
}
.footer-border {
border-color: rgba($white, 0.1);
}
}

View file

@ -0,0 +1,121 @@
//
// ecommerce.scss
//
// product
.search-box{
.form-control{
border-radius: 30px;
padding-left: 40px;
}
.search-icon{
font-size: 16px;
position: absolute;
left: 13px;
top: 0;
line-height: 38px;
}
}
.product-list{
li{
a{
display: block;
padding: 4px 0px;
color: var(--#{$prefix}body-color);
}
}
}
.product-view-nav{
&.nav-pills {
.nav-item{
margin-left: 4px;
}
.nav-link{
width: 36px;
height: 36px;
font-size: 16px;
padding: 0;
line-height: 36px;
text-align: center;
border-radius: 50%;
}
}
}
.product-ribbon{
position: absolute;
right: 0px;
top: 0px;
}
// Product Details
.product-detai-imgs{
.nav{
.nav-link{
margin: 7px 0px;
&.active{
background-color: var(--#{$prefix}tertiary-bg);
}
}
}
}
.product-color{
a{
display: inline-block;
text-align: center;
color: var(--#{$prefix}body-color);
.product-color-item{
margin: 7px;
}
&.active, &:hover{
color: $primary;
.product-color-item{
border-color: $primary !important;
}
}
}
}
// ecommerce cart
.visa-card{
.visa-logo{
line-height: 0.5;
}
.visa-pattern{
position: absolute;
font-size: 385px;
color: rgba($white, 0.05);
line-height: 0.4;
right: 0px;
bottom: 0px;
}
}
// checkout
.checkout-tabs{
.nav-pills{
.nav-link{
margin-bottom: 24px;
text-align: center;
background-color: var(--#{$prefix}secondary-bg);
box-shadow: $box-shadow;
&.active{
background-color: $primary;
}
.check-nav-icon{
font-size: 36px;
}
}
}
}

View file

@ -0,0 +1,210 @@
/* ==============
Email
===================*/
.email-leftbar {
width: 236px;
float: left;
padding: 20px;
border-radius: 5px;
}
.email-rightbar {
margin-left: 260px;
}
.chat-user-box {
p.user-title {
color: var(--#{$prefix}emphasis-color);
font-weight: 500;
}
p {
font-size: 12px;
}
}
@media (max-width: 767px) {
.email-leftbar {
float: none;
width: 100%;
}
.email-rightbar {
margin: 0;
}
}
.mail-list {
a {
display: block;
color: var(--#{$prefix}secondary-color);
line-height: 24px;
padding: 8px 5px;
&.active {
color: $danger;
font-weight: 500;
}
}
}
.message-list {
display: block;
padding-left: 0;
li {
position: relative;
display: block;
height: 50px;
line-height: 50px;
cursor: default;
transition-duration: .3s;
a{
color: var(--#{$prefix}secondary-color);
}
&:hover {
background: var(--#{$prefix}tertiary-bg);
transition-duration: .05s;
}
.col-mail {
float: left;
position: relative;
}
.col-mail-1 {
width: 320px;
.star-toggle,
.checkbox-wrapper-mail,
.dot {
display: block;
float: left;
}
.dot {
border: 4px solid transparent;
border-radius: 100px;
margin: 22px 26px 0;
height: 0;
width: 0;
line-height: 0;
font-size: 0;
}
.checkbox-wrapper-mail {
margin: 15px 10px 0 20px;
}
.star-toggle {
margin-top: 18px;
margin-left: 5px;
}
.title {
position: absolute;
top: 0;
left: 110px;
right: 0;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin-bottom: 0;
}
}
.col-mail-2 {
position: absolute;
top: 0;
left: 320px;
right: 0;
bottom: 0;
.subject,
.date {
position: absolute;
top: 0;
}
.subject {
left: 0;
right: 200px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.date {
right: 0;
width: 170px;
padding-left: 80px;
}
}
&.active,
&.active:hover {
box-shadow: inset 3px 0 0 $primary;
}
&.unread {
background-color: var(--#{$prefix}tertiary-bg);
font-weight: 500;
color: var(--#{$prefix}body-color);
a{
color: var(--#{$prefix}body-color);
font-weight: 500;
}
}
}
.checkbox-wrapper-mail {
cursor: pointer;
height: 20px;
width: 20px;
position: relative;
display: inline-block;
background-color: var(--#{$prefix}secondary-bg);
box-shadow: inset 0 0 0 1px var(--#{$prefix}border-color-translucent);
border-radius: 1px;
input {
opacity: 0;
cursor: pointer;
}
input:checked ~ label {
opacity: 1;
}
label {
position: absolute;
height: 20px;
width: 20px;
left: 0;
cursor: pointer;
opacity: 0;
margin-bottom: 0;
transition-duration: .05s;
top: 0;
&:before {
content: "\F012C";
font-family: "Material Design Icons";
top: 0;
height: 20px;
color: var(--#{$prefix}body-color);
width: 20px;
position: absolute;
margin-top: -16px;
left: 4px;
font-size: 13px;
}
}
}
}
@media (max-width: 575.98px) {
.message-list li .col-mail-1 {
width: 200px;
}
}

View file

@ -0,0 +1,35 @@
//
// Extras pages.scss
//
// pricing
.plan-box{
.plan-btn{
position: relative;
&::before{
content: "";
position: absolute;
width: 100%;
height: 2px;
background: var(--#{$prefix}border-color);
left: 0px;
right: 0px;
top: 12px;
}
}
}
// blog
.blog-play-icon{
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
margin: 0px auto;
}

View file

@ -0,0 +1,51 @@
//
// File manager.scss
//
// file manager
.filemanager-sidebar{
@media (min-width: 1200px){
min-width: 230px;
max-width: 230px;
}
@media (min-width: 1366px){
min-width: 280px;
max-width: 280px;
}
}
.categories-list{
padding: 4px 0;
li{
a{
display: block;
padding: 8px 12px;
color: var(--#{$prefix}body-color);
font-weight: $font-weight-medium;
}
&.active{
a{
color: $primary;
}
}
ul{
padding-left: 16px;
li{
a{
padding: 4px 12px;
color: var(--#{$prefix}secondary-color);
font-size: 13px;
font-weight: $font-weight-normal;
}
}
}
}
}

View file

@ -0,0 +1,13 @@
//
// _jobs.scss
//
.jobs-categories {
a {
color: var(--#{$prefix}body-color);
transition: all 0.5s ease;
&:hover {
color: $primary;
}
}
}

View file

@ -0,0 +1,14 @@
//
// projects.scss
//
// project list
.project-list-table {
border-collapse: separate;
border-spacing: 0 12px;
tr {
background-color: var(--#{$prefix}secondary-bg);
}
}

View file

@ -0,0 +1,83 @@
//
// timeline.scss
//
/************** Horizontal timeline **************/
.hori-timeline{
.events{
.event-list{
text-align: center;
display: block;
.event-down-icon{
position: relative;
&::before{
content: "";
position: absolute;
width: 100%;
top: 16px;
left: 0;
right: 0;
border-bottom: 3px dashed var(--#{$prefix}border-color);
}
.down-arrow-icon{
position: relative;
background-color: var(--#{$prefix}secondary-bg);
padding: 4px;
}
}
&:hover{
.down-arrow-icon{
animation: fade-down 1.5s infinite linear;
}
}
&.active{
.down-arrow-icon{
animation: fade-down 1.5s infinite linear;
&:before {
content: "\ec4c";
}
}
}
}
}
}
/************** vertical timeline **************/
.verti-timeline{
border-left: 3px dashed var(--#{$prefix}border-color);
margin: 0 10px;
.event-list{
position: relative;
padding: 0px 0px 40px 30px;
.event-timeline-dot{
position: absolute;
left: -9px;
top: 0px;
z-index: 9;
font-size: 16px;
}
.event-content{
position: relative;
border: 2px solid var(--#{$prefix}border-color);
border-radius: 7px;
}
&.active{
.event-timeline-dot{
color: $primary;
}
}
&:last-child{
padding-bottom: 0px;
}
}
}

Some files were not shown because too many files have changed in this diff Show more