project setup
This commit is contained in:
9
.env
Normal file
9
.env
Normal file
@@ -0,0 +1,9 @@
|
||||
VITE_FIREBASE_API_KEY=AIzaSyBxt-j-9yVwt-3iPLp1Px-a038ZXwAiHOs
|
||||
VITE_FIREBASE_AUTH_DOMAIN=app.contexted.io
|
||||
VITE_FIREBASE_DATABASE_URL=https://contexted-f8b4e.firebaseio.com
|
||||
VITE_FIREBASE_PROJECT_ID=contexted-f8b4e
|
||||
VITE_FIREBASE_STORAGE_BUCKET=contexted-f8b4e.appspot.com
|
||||
VITE_FIREBASE_MESSAGE_SENDER_ID=1048273547256zz
|
||||
VITE_FIREBASE_APP_ID=1:1048273547256:web:c5516617eeeabd470f700d
|
||||
VITE_FIREBASE_MEASUREMENT_ID=G-ZMQXB5HFNV
|
||||
VITE_MIXPANEL_API_TOKEN=786d5c92512f20e9de9eac97c65aed36
|
||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>Vite + Vue + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app" class="bg-light"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
3553
package-lock.json
generated
Normal file
3553
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,15 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"bootstrap": "^5.2.3",
|
||||
"bootstrap-icons": "^1.10.5",
|
||||
"firebase": "^9.20.0",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"sass": "^1.62.1",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.3.2",
|
||||
"vue-tsc": "^1.4.2"
|
||||
|
||||
41
src/App.vue
41
src/App.vue
@@ -1,30 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import SideBar from './components/SideBar.vue'
|
||||
import useNotes from './composables/useNotes'
|
||||
|
||||
const { notes } = useNotes()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a href="https://vitejs.dev" target="_blank">
|
||||
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://vuejs.org/" target="_blank">
|
||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
||||
</a>
|
||||
<TopBar />
|
||||
<div class="container g-3 d-flex h-100" style="padding-top: 50px">
|
||||
<SideBar class="py-3" />
|
||||
<div id="main" class="bg-white border-start border-end px-4 py-3">
|
||||
main
|
||||
<pre>{{ notes }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<HelloWorld msg="Vite + Vue" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #42b883aa);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
#main {
|
||||
overflow: auto;
|
||||
flex: 1 1 0;
|
||||
}</style>
|
||||
|
||||
9
src/assets/style.scss
Normal file
9
src/assets/style.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
$primary: #1e4bc4;
|
||||
|
||||
@import 'bootstrap/scss/bootstrap';
|
||||
|
||||
body,
|
||||
body > div,
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<button type="button" @click="count++">count is {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test HMR
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Check out
|
||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||
>create-vue</a
|
||||
>, the official Vue + Vite starter
|
||||
</p>
|
||||
<p>
|
||||
Install
|
||||
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
||||
in your IDE for a better DX
|
||||
</p>
|
||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
48
src/components/SideBar.vue
Normal file
48
src/components/SideBar.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<script setup lang="ts">
|
||||
import useNotes from '../composables/useNotes'
|
||||
import SideBarMenu from './SideBar/SideBarMenu.vue'
|
||||
import SideBarMenuItem from './SideBar/SideBarMenuItem.vue'
|
||||
const { rootNote } = useNotes()
|
||||
|
||||
interface ViewMode {
|
||||
name: string
|
||||
icon: string
|
||||
}
|
||||
const viewModes: ViewMode[] = [
|
||||
{ name: 'Note', icon: 'card-text' },
|
||||
{ name: 'List', icon: 'list-task' },
|
||||
{ name: 'Mindmap', icon: 'diagram-3' },
|
||||
]
|
||||
</script>
|
||||
<template>
|
||||
<div id="sidebar" class="position-relative pe-3 d-flex flex-column" style="width: 200px">
|
||||
<SideBarMenu>
|
||||
<template #header>Root note</template>
|
||||
<template #items>
|
||||
<SideBarMenuItem icon="house">{{
|
||||
rootNote?.title
|
||||
}}</SideBarMenuItem>
|
||||
</template>
|
||||
</SideBarMenu>
|
||||
<SideBarMenu>
|
||||
<template #header>View mode</template>
|
||||
<template #items>
|
||||
<SideBarMenuItem v-for="viewMode in viewModes" :icon="viewMode.icon">{{
|
||||
viewMode.name
|
||||
}}</SideBarMenuItem>
|
||||
</template>
|
||||
</SideBarMenu>
|
||||
<SideBarMenu>
|
||||
<template #header>Recent notes</template>
|
||||
<template #items>
|
||||
<SideBarMenuItem>{{ rootNote?.title }}</SideBarMenuItem>
|
||||
</template>
|
||||
</SideBarMenu>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
#sidebar {
|
||||
gap: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
13
src/components/SideBar/SideBarMenu.vue
Normal file
13
src/components/SideBar/SideBarMenu.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-uppercase fw-semibold header">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
<slot name="items"></slot>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.header {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
20
src/components/SideBar/SideBarMenuItem.vue
Normal file
20
src/components/SideBar/SideBarMenuItem.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
icon?: string
|
||||
}>()
|
||||
</script>
|
||||
<template>
|
||||
<a class="text-opacity-50 text-decoration-none w-100 d-block link-secondary">
|
||||
<i :class="`bi bi-${props.icon}`" class="me-2" v-if="props.icon"></i
|
||||
><slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
a {
|
||||
cursor: pointer;
|
||||
border-radius: var(--bs-border-radius);
|
||||
}
|
||||
a:hover {
|
||||
background-color: var(--bs-gray-300);
|
||||
}
|
||||
</style>
|
||||
10
src/components/TopBar.vue
Normal file
10
src/components/TopBar.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div
|
||||
class="bg-primary position-absolute top-0 start-0 end-0"
|
||||
style="height: 50px"
|
||||
>
|
||||
<div class="container g-3 h-100 d-flex align-items-center text-white">
|
||||
top bar
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
15
src/composables/useNotes.ts
Normal file
15
src/composables/useNotes.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ref } from 'vue'
|
||||
const notes = ref<Note[]>([])
|
||||
|
||||
export default function useNotes() {
|
||||
const setDefaultNotes = (defaultNotes: Note[]) => {
|
||||
notes.value = defaultNotes.map((note) => ({
|
||||
...note,
|
||||
created: new Date().getTime(),
|
||||
modified: new Date().getTime(),
|
||||
}))
|
||||
}
|
||||
const rootNote = notes.value.find((note) => note.isRoot)
|
||||
|
||||
return { notes, setDefaultNotes, rootNote }
|
||||
}
|
||||
17
src/global.d.ts
vendored
Normal file
17
src/global.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
declare global {
|
||||
interface Note {
|
||||
id?: string
|
||||
title: string
|
||||
content: string
|
||||
created: number
|
||||
modified: number
|
||||
isRoot: boolean
|
||||
wordCount?: number
|
||||
links?: {
|
||||
to: string[]
|
||||
from: string[]
|
||||
}
|
||||
isRoot?: boolean
|
||||
}
|
||||
}
|
||||
export {}
|
||||
@@ -1,5 +1,10 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import './assets/style.scss'
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||
import App from './App.vue'
|
||||
import useNotes from './composables/useNotes'
|
||||
import { defaultNotes } from './utils/defaultNotes'
|
||||
const { setDefaultNotes } = useNotes()
|
||||
setDefaultNotes(defaultNotes)
|
||||
|
||||
createApp(App).mount('#app')
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
20
src/utils/defaultNotes.ts
Normal file
20
src/utils/defaultNotes.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export const defaultNotes: Note[] = [
|
||||
{
|
||||
isRoot: true,
|
||||
title: 'Your first note',
|
||||
content: `Contexted is a **relational note-taking app**. Use it as your personal knowledge base, research assistent or just to map out thoughts.\n\n
|
||||
### **How does it work?**
|
||||
* Create a new note by typing words between [[brackets]]
|
||||
* Click on **Mindmap mode** in the menu left to visualize your notes
|
||||
\n
|
||||
Let's get started!`,
|
||||
created: 0,
|
||||
modified: 0,
|
||||
},
|
||||
{
|
||||
title: 'brackets',
|
||||
content: `If you type square brackets around text a link is created automatically. Like magic!`,
|
||||
created: 0,
|
||||
modified: 0,
|
||||
},
|
||||
]
|
||||
15
src/utils/firebase.ts
Normal file
15
src/utils/firebase.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { initializeApp } from 'firebase/app'
|
||||
|
||||
// TODO: Replace the following with your app's Firebase project configuration
|
||||
const firebaseConfig: any = {
|
||||
apiKey: import.meta.env.VUE_APP_FIREBASE_API_KEY,
|
||||
authDomain: import.meta.env.VUE_APP_FIREBASE_AUTH_DOMAIN,
|
||||
databaseURL: import.meta.env.VUE_APP_FIREBASE_DATABASE_URL,
|
||||
projectId: import.meta.env.VUE_APP_FIREBASE_PROJECT_ID,
|
||||
storageBucket: import.meta.env.VUE_APP_FIREBASE_STORAGE_BUCKET,
|
||||
messagingSenderId: import.meta.env.VUE_APP_FIREBASE_MESSAGE_SENDER_ID,
|
||||
appId: import.meta.env.VUE_APP_FIREBASE_APP_ID,
|
||||
measurementId: import.meta.env.VUE_APP_FIREBASE_MEASUREMENT_ID,
|
||||
}
|
||||
|
||||
export const app = initializeApp(firebaseConfig)
|
||||
Reference in New Issue
Block a user