Skip to content

Commit

Permalink
feat: improve search.
Browse files Browse the repository at this point in the history
  • Loading branch information
masterkram committed Jul 2, 2024
1 parent f1e587e commit b7e279f
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 45 deletions.
49 changes: 39 additions & 10 deletions .demo/content/board/agency-os.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,36 @@ github: https://github.com/directus-labs/agency-os

# Agency OS

Combination of hackable tools to run any type of digital agency.
Combination of key hackable tools to run any type of digital agency. Created by **Directus** and **NuxtLabs**.

## Features
Agency OS is heavily based on using **Directus** as a backend as a service, this will store all of the data related to your agency, projects and clients.

![agency os marketing site](/agency-os.png)

## Main Features

The agency os kit is made out of the following 3 tools:
+ CRM
+ Marketing website
+ Client Portal

### CRM
A CRM (customer resource management) is a common type of business software.

A CRM is used to keep track of customers of a business.
A CRM is mainly used to keep track of customers of a business.

The exact way this software is used can vary highly from business to business because of differences in how they operate.

Most CRMs allow you to:
+ create customers
+ assign them to one or more employees.
+ save files and other metadata tied to the customer.
The agency OS CRM allows you to:
+ manage organizations and contacts
+ create a sales pipeline
+ make dynamic project proposals
+ use project and task management
+ create customizable project templates
+ access to invoicing and expense tracking
+ create dashboards
+ apply automation


### Marketing Website

Expand All @@ -38,16 +49,34 @@ This website can be used to:
+ show of past projects of the agency as case studies.
+ write articles for content based marketing of the agency.

The features that the website already has created for you are
+ dynamic page builder based on html and components.
+ blog posts with categories
+ dynamic form generation with validation
+ technical SEO support
+ global search
+ dark mode

### Client Portal

A client portal can be a valuable addition to the toolbox of an agency.
It let's clients of your agency login to a platform where you can provide them updates of how their project is progressing.
It let's clients of your agency log in to a platform where you can provide them updates of how their project is progressing.

The agency OS client portal has the following features:
+ view projects, tasks and files
+ pay invoices with stripe
+ assign tasks to clients.

## Getting Started

Watch the [youtube playlist](https://www.youtube.com/playlist?list=PLD--x9rY3ZL1tPNZxCTE_-IsFTrFGKHH-) to get a impression and understand how to setup Agency OS.

The [github readme](https://github.com/directus-labs/agency-os?tab=readme-ov-file#installation-and-development) also gives a good step by step plan of how to deploy your own agency os.

**Links:**
<div class="flex gap-2">

:linkButton{:href="github" icon="ph:github-logo"}[github]
:linkButton{:href="github" icon="ph:github-logo-bold"}[github]

:linkButton{:href="demo" icon="ph:laptop" color="indigo"}[demo]
:linkButton{:href="demo" icon="ph:laptop-bold" color="indigo"}[demo]
</div>
22 changes: 22 additions & 0 deletions .demo/content/board/nightrunner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
github: https://github.com/notKamui/Nightrunner
---
# Nightrunner

Minimal starter template containing internationalization with i18n and styling using UnoCSS.

## Features
+ localization
+ dark and light theme

## Stack

| Use | Name |
| :--- | :---- |
| framework | nuxt ⛰️ |
| component library | UnoCSS 1️⃣ |
| state management | pinia 🍍 |

## Getting Started

:linkButton{icon="ph:github-logo"}[github]
15 changes: 15 additions & 0 deletions .demo/content/board/primevue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
github: https://github.com/sfxcode/nuxt3-primevue-starter
---

# Prime Vue

Styling based starter including prime vue components.

## Features

## Stack

| use | name |
| --- | ---- |
| | |
41 changes: 40 additions & 1 deletion .demo/content/board/supastarter.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
---
price: 299
tags:
- SAAS
---

# Supastarter

Saas starter kit.
Extensive paid SaaS boilerplate with many key features.

## Features

+ 🔐 Authentication
+ 💸 Payments
+ 🏢 Multi Tenancy
+ 💻 Super Admin
+ 🦹 User Impersonation
+ 📋 SaaS onboarding flow
+ 🤖 AI
+ 🗺️ Internationalization
+ 🖥️ SaaS landing page
+ 📰 SaaS Blog
+ 📚 SaaS Documentation
+ 📃 SaaS Legal Pages
+ 📊 Analytics
+ 📧 Newsletter signup
+ 🖌️ Customizable UI
+ 🌙 Dark mode
+ 📧 Custom Emails

## Stack

| Use | Name |
|:--- |:---- |
| Authentication | Lucia Auth |
| Payments | Lemonsqueezy / Stripe |
| LLM Integration | OpenAI |
| Styling | tailwindcss, radixUI |
| Database | MySQL, SQLite, Postgres, mongoDB |
| Database Client | Prisma |
| API | trpc |
| Mailing | Vue Email |


## Getting Started

Binary file added .demo/public/agency-os.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion components/content/BlogGrid.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
const { data } = await useAsyncData('board', () => queryContent('/blog').where({ _path: { $ne: "/blog" } }).find());
const { data } = await useAsyncData('blog', () => queryContent('/blog').where({ _path: { $ne: "/blog" } }).find());
</script>

<template>
Expand Down
21 changes: 21 additions & 0 deletions components/content/Bookmark.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
const props = defineProps(['link']);
const result = await fetch(props.link);
</script>

<template>
<div class="border rounded hover:bg-gray-400">
<div>
<p>Million Song Dataset</p>
<p>Predict which songs a user will listen to</p>
</div>

{{ result.text() }}

<div>
<img src="" alt="">
<span></span>
</div>
</div>
</template>
30 changes: 16 additions & 14 deletions components/content/DirectoryGrid.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
<script setup lang="ts">
import type SearchData from '../../types/SearchData';
const search: Ref<string> = useState("search");
const tags: Ref<string[]> = useState("tags");
const search: Ref<SearchData> = useState("search", () => ({ query: "", tags: [] }));
const { data, refresh } = useAsyncData('board', () => {
const query = queryContent('/board');
// Conditionally add the 'where' clause if the search input is not empty
if (search.value.query) {
query.where({
$or: [
{ title: { $containsAny: search.value.query.split(' ') } },
{ description: { $containsAny: search.value.query.split(' ') } },
]
});
if (search.value) {
query.where({ $or: [{ title: { $icontains: search.value } }, { description: { $icontains: search.value } }] });
}
if (tags.value && tags.value.length > 0) {
query.where({ 'tags': { $containsAny: tags.value } });
}
return query.sort({ sponsored: 1 }).find();
}, { watch: [search] });
}, { watch: [search, tags] });
watch(search, () => {
refresh();
});
watch(
[search, tags],
() => {
refresh();
},
{ deep: true }
);
</script>

<template>
Expand Down
27 changes: 14 additions & 13 deletions components/content/Search.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<script setup lang="ts">
import type SearchData from '../../types/SearchData';
const router = useRouter();
const search: Ref<SearchData> = useState("search", () => ({ query: "", tags: [] }));
const search: Ref<string> = useState("search");
const selectedTags: Ref<string[]> = useState("tags", () => []);
const searchTag = useAppConfig().directory.searchTag;
watch(search, (newValue, previous) => {
router.push({
query: { search: newValue.query.trim() },
})
})
watch(
[search, selectedTags],
() => {
router.push({
query: { search: search.value.trim(), tags: selectedTags.value },
});
},
);
const searchInput = useKeyFocus();
Expand All @@ -22,16 +24,15 @@ const availableTags = computed(() => {
});
function removeTag(myTag: string) {
selectedTags.value = selectedTags.value.filter(e => e != myTag);
const index = selectedTags.value.indexOf(myTag);
selectedTags.value.splice(index, 1);
}
const selectedTags: Ref<Array<string>> = ref([]);
function addTag(event: any) {
const select = event.target as HTMLSelectElement;
const selectedValue = select.value;
if (selectedValue && !selectedTags.value.includes(selectedValue)) {
if (selectedTags.value && !selectedTags.value.includes(selectedValue)) {
selectedTags.value.push(selectedValue);
// Optionally clear the selection after adding
select.value = '';
Expand All @@ -43,7 +44,7 @@ function addTag(event: any) {
<template>
<div class="mb-10 not-prose">
<div class="relative flex items-center">
<input v-model="search.query" ref="searchInput"
<input v-model="search" ref="searchInput"
class="block w-full rounded-md border-0 py-2 pr-14 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6"
:placeholder="searchTag">
<div class="absolute inset-y-0 right-0 flex py-1.5 pr-1.5">
Expand Down
8 changes: 6 additions & 2 deletions components/content/TwoColumnHero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const props = defineProps(['imgSrc']);
<template>
<div class="flex items-start pt-20 pb-20 gap-10">
<div>
<h1>
<h1 class="text-balance font-extrabold tracking-tight">
<ContentSlot :use="$slots.default" unwrap="h1" />
</h1>
<ContentSlot :use="$slots.description" />
Expand All @@ -17,7 +17,11 @@ const props = defineProps(['imgSrc']);
</template>

<style scoped lang="postcss">
h1 span {
.highlight span {
@apply bg-gray-800 text-white px-1 -rotate-6;
}
.dashedcue span {
@apply underline underline-offset-4 decoration-primary-600 decoration-dashed;
}
</style>
3 changes: 3 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ export default defineNuxtConfig({
// https://content.nuxt.com/
content: {
documentDriven: true,
experimental: {
search: true,
},
},
});
4 changes: 0 additions & 4 deletions types/SearchData.ts

This file was deleted.

0 comments on commit b7e279f

Please sign in to comment.