├── .editorconfig ├── .env ├── .env.example ├── .forestry ├── front_matter │ └── templates │ │ ├── blog-post.yml │ │ └── pages.yml └── settings.yml ├── .github └── dependabot.yml ├── .gitignore ├── .prettierrc.js ├── README.md ├── assets └── styles │ ├── _base.scss │ ├── _content-typography.scss │ ├── _editor.scss │ ├── _fonts.scss │ ├── _loader.scss │ ├── _markdown.scss │ └── app.scss ├── components ├── Alert.vue ├── Loader.vue ├── Logos │ ├── Dark.vue │ └── Text.vue ├── Navbar │ ├── Links.vue │ ├── Navbar.vue │ ├── SearchInput.vue │ └── UserAction.vue ├── SlideOverSidebar.vue ├── app-image.vue ├── article-card.vue ├── article-editor │ ├── index.vue │ ├── md.vue │ ├── meta.vue │ ├── ribbon.vue │ └── thumbnail.vue ├── comments │ ├── comment.vue │ ├── editor.vue │ └── index.vue ├── contest-banner.vue ├── contest-guideline-pages.vue ├── count-down-wrapper.vue ├── count-down.vue ├── dashboard │ ├── aside.vue │ ├── profile-info.vue │ ├── profile-photo.vue │ ├── profile-readme.vue │ ├── profile-social.vue │ └── profile-tabs.vue ├── form │ ├── button.vue │ ├── copyable.vue │ ├── file-uploader.vue │ ├── input.vue │ └── textarea.vue ├── layout │ └── three-columns.vue ├── markdown-td.vue ├── page-location.vue ├── resizeable-textarea.vue ├── share-button.vue ├── sidebar-left.vue ├── sidebar-right.vue ├── user-info-card.vue ├── vote-wrapper.vue └── widgets │ ├── action-links.vue │ ├── discord.vue │ ├── fake-editor.vue │ ├── latest-registered-users.vue │ ├── links.vue │ ├── login-buttons.vue │ ├── login.vue │ ├── social-links.vue │ ├── sponsor.vue │ ├── tags.vue │ ├── top-writters.vue │ └── vuejs-bootcamp.vue ├── content ├── _contest │ ├── guides │ │ ├── writing-tricks.md │ │ └── writting-guidelines.md │ └── welcome.md └── _pages │ ├── about.md │ ├── md-demo.md │ ├── privacy.md │ └── terms-and-conditions.md ├── helpers └── editorjsParser.js ├── jsconfig.json ├── layouts ├── blank.vue ├── dashboard.vue ├── default.vue ├── left-sidebar.vue └── three-columns.vue ├── mixins ├── bookmark.js ├── form-validation.js ├── reactions.js ├── share.js ├── social-login.js ├── upload.js └── votes.js ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages ├── _username │ ├── _slug.vue │ ├── articles.vue │ └── index.vue ├── auth │ ├── login.vue │ ├── oauth-callback.vue │ └── register.vue ├── contest │ ├── _slug.vue │ └── index.vue ├── dashboard │ ├── bookmarks.vue │ ├── diaries │ │ ├── draft.vue │ │ ├── edit │ │ │ └── _id.vue │ │ ├── index.vue │ │ └── published.vue │ ├── index.vue │ ├── sessions.vue │ ├── settings.vue │ └── tokens.vue ├── index.vue ├── pages │ └── _slug.vue ├── tags │ └── _tag.vue ├── test.vue └── thumbnail.vue ├── plugins ├── clickaway.js ├── editor.js ├── multi-select.js ├── resizeable-input.js ├── toast.client.js ├── tour.client.js └── visibility-observer.js ├── static ├── README.md ├── branding │ ├── full-logo-dark.svg │ ├── full-logo-light.svg │ ├── icon-dark.svg │ ├── icon-light.svg │ ├── text-logo-dark.svg │ └── text-logo-light.svg ├── favicon.ico ├── favicon.svg ├── fonts │ ├── Boshonto.woff │ ├── Boshonto.woff2 │ ├── KohinoorBangla-Bold.woff │ ├── KohinoorBangla-Light.woff │ ├── KohinoorBangla-Medium.woff │ ├── KohinoorBangla-Regular.woff │ ├── KohinoorBangla-Semibold.woff │ ├── kohinoor-webfont.woff │ ├── kohinoor-webfont.woff2 │ ├── kohinoor_bold-webfont.woff │ ├── kohinoor_bold-webfont.woff2 │ ├── kohinoor_light-webfont.woff │ ├── kohinoor_light-webfont.woff2 │ ├── kohinoor_medium-webfont.woff │ ├── kohinoor_medium-webfont.woff2 │ └── stylesheet.css ├── icons │ ├── external-link-sm.svg │ └── search-by-algolia-dark-background.svg ├── images │ ├── fabulous-late-night-working.png │ ├── hero.png │ ├── robots-drones-artificial-intelligence-1.png │ └── sadface.gif ├── reactions │ ├── CHEER.png │ ├── FLYHIGH.png │ ├── HEART.png │ ├── LIKE.png │ ├── MONEY.png │ ├── PARTY.png │ ├── TROPHY.png │ └── UNICORN.png └── techdiary-imac-mockup.png ├── store ├── README.md ├── index.js ├── search.js └── ui.js ├── tailwind.config.js ├── todo.md └── vercel.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | NUXT_ENV_BASE_URL=http://techdiary.test:3000 2 | NUXT_ENV_API_URL=http://api.techdiary.test 3 | NUXT_APP_CLOUDINARY_CLOUDNAME=kingrayhan 4 | NUXT_ENV_HOST=techdiary.test 5 | NUXT_APP_GOOGLE_ANALYTICS_ID=UA-1209849-1 6 | NUXT_ENV_ALGOLIA_APP_ID=IA88PX3T8O 7 | NUXT_ENV_ALGOLIA_API_KEY=898cb2ef32ee94ecbe0f7f7ef60320e9 -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NUXT_ENV_API_URL= 2 | NUXT_APP_CLOUDINARY_CLOUDNAME= 3 | NUXT_ENV_HOST= 4 | -------------------------------------------------------------------------------- /.forestry/front_matter/templates/blog-post.yml: -------------------------------------------------------------------------------- 1 | --- 2 | label: Blog post 3 | hide_body: false 4 | fields: 5 | - name: tags 6 | type: tag_list 7 | default: [] 8 | label: Tags 9 | - name: thumbnail 10 | type: file 11 | config: 12 | maxSize: 64 13 | label: Thumbnail 14 | - name: categories 15 | type: select 16 | default: [] 17 | config: 18 | required: false 19 | options: 20 | - featured 21 | - news 22 | source: 23 | type: simple 24 | section: 25 | file: 26 | path: 27 | label: Categories 28 | -------------------------------------------------------------------------------- /.forestry/front_matter/templates/pages.yml: -------------------------------------------------------------------------------- 1 | --- 2 | label: Pages 3 | hide_body: false 4 | fields: 5 | - name: title 6 | type: text 7 | config: 8 | required: false 9 | label: Title 10 | description: Page title 11 | - name: slug 12 | type: text 13 | config: 14 | required: false 15 | label: Page slug 16 | description: A unique slug for the page 17 | - name: thumbnail 18 | type: file 19 | config: 20 | maxSize: 64 21 | label: Thumbnail 22 | -------------------------------------------------------------------------------- /.forestry/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | new_page_extension: md 3 | auto_deploy: false 4 | admin_path: '' 5 | webhook_url: 6 | sections: 7 | - type: directory 8 | path: content 9 | label: Contents 10 | create: all 11 | match: "**/*" 12 | templates: 13 | - pages 14 | upload_dir: static-pages-assets 15 | public_path: https://res.cloudinary.com/techdiary-dev/image/upload 16 | front_matter_path: '' 17 | use_front_matter_path: 18 | file_template: ":filename:" 19 | build: 20 | install_dependencies_command: npm install 21 | preview_docker_image: forestryio/node:12 22 | mount_path: "/srv" 23 | working_dir: "/srv" 24 | instant_preview_command: npm run develop 25 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | # Maintain dependencies for GitHub Actions 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | 10 | # Maintain dependencies for npm 11 | - package-ecosystem: "npm" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: "es5", 3 | tabWidth: 4, 4 | semi: true, 5 | singleQuote: false, 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # techdiary.dev frontend 2 | 3 | ### Build Setup 4 | 5 | ```bash 6 | # install dependencies 7 | $ npm install 8 | 9 | # serve with hot reload at localhost:3000 10 | $ npm run dev 11 | 12 | # build for production and launch server 13 | $ npm run build 14 | $ npm run start 15 | 16 | # generate static project 17 | $ npm run generate 18 | ``` 19 | -------------------------------------------------------------------------------- /assets/styles/_base.scss: -------------------------------------------------------------------------------- 1 | img { 2 | max-width: 100%; 3 | } 4 | 5 | button { 6 | @apply focus:outline-none; 7 | } 8 | -------------------------------------------------------------------------------- /assets/styles/_content-typography.scss: -------------------------------------------------------------------------------- 1 | .content-typography { 2 | @apply prose md:prose-xl prose-slate dark:prose-invert; 3 | @apply max-w-none; 4 | 5 | @apply prose-code:p-0; 6 | @apply prose-a:inline-block; 7 | @apply prose-p:p-0; 8 | @apply prose-img:inline-block; 9 | 10 | @apply prose-headings:font-semibold; 11 | 12 | @apply prose-h1:text-xl md:prose-h1:text-2xl; 13 | @apply prose-h2:text-lg md:prose-h2:text-2xl; 14 | @apply prose-h3:text-base md:prose-h3:text-xl; 15 | @apply prose-h4:text-base md:prose-h4:text-xl; 16 | 17 | iframe { 18 | @apply w-full aspect-[16/9]; 19 | } 20 | 21 | .table-of-contents { 22 | @apply bg-slate-100 py-2 dark:bg-slate-700 prose-sm md:prose-base; 23 | @apply mb-4; 24 | } 25 | 26 | .heading-permalink { 27 | @apply md:scroll-mt-20 scroll-mt-16; 28 | @apply mr-3; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /assets/styles/_editor.scss: -------------------------------------------------------------------------------- 1 | .td-editor { 2 | h1, 3 | h2, 4 | h3, 5 | h4, 6 | h5 { 7 | @apply font-bold; 8 | } 9 | 10 | h1 { 11 | @apply text-2xl; 12 | } 13 | 14 | h2 { 15 | @apply text-xl; 16 | } 17 | h3 { 18 | @apply text-lg; 19 | } 20 | h4 { 21 | @apply text-base; 22 | } 23 | 24 | .ce-block--stretched { 25 | position: relative; 26 | @media (min-width: 768px) { 27 | position: relative; 28 | margin-left: calc(50% - 32vw); 29 | margin-right: calc(50% - 32vw); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assets/styles/_fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Boshonto"; 3 | src: url("~/static/fonts/Boshonto.woff") format("woff"), 4 | url("~/static/fonts/Boshonto.woff2") format("woff2"); 5 | } 6 | 7 | @font-face { 8 | font-family: "KohinoorBangla"; 9 | src: url("~/static/fonts/KohinoorBangla-Light.woff") format("woff"); 10 | font-weight: 300; 11 | } 12 | 13 | @font-face { 14 | font-family: "KohinoorBangla"; 15 | src: url("~/static/fonts/KohinoorBangla-Regular.woff") format("woff"); 16 | font-weight: 400; 17 | } 18 | 19 | @font-face { 20 | font-family: "KohinoorBangla"; 21 | src: url("~/static/fonts/KohinoorBangla-Medium.woff") format("woff"); 22 | font-weight: 500; 23 | } 24 | 25 | @font-face { 26 | font-family: "KohinoorBangla"; 27 | src: url("~/static/fonts/KohinoorBangla-Semibold.woff") format("woff"); 28 | font-weight: 600; 29 | } 30 | 31 | @font-face { 32 | font-family: "KohinoorBangla"; 33 | src: url("~/static/fonts/KohinoorBangla-Bold.woff") format("woff"); 34 | font-weight: 700; 35 | } 36 | -------------------------------------------------------------------------------- /assets/styles/_loader.scss: -------------------------------------------------------------------------------- 1 | .sk-chase { 2 | width: 40px; 3 | height: 40px; 4 | position: relative; 5 | animation: sk-chase 2.5s infinite linear both; 6 | } 7 | 8 | .sk-chase-dot { 9 | width: 100%; 10 | height: 100%; 11 | position: absolute; 12 | left: 0; 13 | top: 0; 14 | animation: sk-chase-dot 2s infinite ease-in-out both; 15 | } 16 | 17 | .sk-chase-dot:before { 18 | @apply bg-gray-800 dark:bg-gray-100; 19 | content: ''; 20 | display: block; 21 | width: 25%; 22 | height: 25%; 23 | border-radius: 100%; 24 | animation: sk-chase-dot-before 2s infinite ease-in-out both; 25 | } 26 | 27 | .sk-chase-dot:nth-child(1) { 28 | animation-delay: -1.1s; 29 | } 30 | 31 | .sk-chase-dot:nth-child(2) { 32 | animation-delay: -1s; 33 | } 34 | 35 | .sk-chase-dot:nth-child(3) { 36 | animation-delay: -0.9s; 37 | } 38 | 39 | .sk-chase-dot:nth-child(4) { 40 | animation-delay: -0.8s; 41 | } 42 | 43 | .sk-chase-dot:nth-child(5) { 44 | animation-delay: -0.7s; 45 | } 46 | 47 | .sk-chase-dot:nth-child(6) { 48 | animation-delay: -0.6s; 49 | } 50 | 51 | .sk-chase-dot:nth-child(1):before { 52 | animation-delay: -1.1s; 53 | } 54 | 55 | .sk-chase-dot:nth-child(2):before { 56 | animation-delay: -1s; 57 | } 58 | 59 | .sk-chase-dot:nth-child(3):before { 60 | animation-delay: -0.9s; 61 | } 62 | 63 | .sk-chase-dot:nth-child(4):before { 64 | animation-delay: -0.8s; 65 | } 66 | 67 | .sk-chase-dot:nth-child(5):before { 68 | animation-delay: -0.7s; 69 | } 70 | 71 | .sk-chase-dot:nth-child(6):before { 72 | animation-delay: -0.6s; 73 | } 74 | 75 | @keyframes sk-chase { 76 | 100% { 77 | transform: rotate(360deg); 78 | } 79 | } 80 | 81 | @keyframes sk-chase-dot { 82 | 80%, 83 | 100% { 84 | transform: rotate(360deg); 85 | } 86 | } 87 | 88 | @keyframes sk-chase-dot-before { 89 | 50% { 90 | transform: scale(0.4); 91 | } 92 | 100%, 93 | 0% { 94 | transform: scale(1); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /assets/styles/_markdown.scss: -------------------------------------------------------------------------------- 1 | .markdown { 2 | @apply text-dark leading-normal break-words; 3 | 4 | & > * + * { 5 | @apply mt-0 mb-4; 6 | } 7 | 8 | li + li { 9 | @apply mt-1; 10 | } 11 | 12 | li > p + p { 13 | @apply mt-6; 14 | } 15 | 16 | strong { 17 | @apply font-semibold; 18 | a { 19 | @apply font-bold; 20 | } 21 | } 22 | 23 | a { 24 | @apply text-blue-400 font-normal; 25 | } 26 | 27 | h1 { 28 | @apply leading-tight border-b text-4xl font-semibold mb-4 mt-6 pb-2; 29 | } 30 | 31 | h2 { 32 | @apply leading-tight border-b text-2xl font-semibold mb-4 mt-6 pb-2; 33 | } 34 | 35 | h3 { 36 | @apply leading-snug text-lg font-semibold mb-4 mt-6; 37 | } 38 | 39 | h4 { 40 | @apply leading-none text-base font-semibold mb-4 mt-6; 41 | } 42 | 43 | h5 { 44 | @apply leading-tight text-sm font-semibold mb-4 mt-6; 45 | } 46 | 47 | h6 { 48 | @apply leading-tight text-sm font-semibold mb-4 mt-6; 49 | } 50 | 51 | blockquote { 52 | @apply text-base border-l-4 border-gray-300 pl-4 pr-4; 53 | } 54 | 55 | code { 56 | @apply font-mono text-sm inline bg-gray-200 rounded px-1 py-1; 57 | } 58 | 59 | img { 60 | @apply inline-block; 61 | } 62 | 63 | pre { 64 | @apply bg-gray-100 rounded p-4; 65 | code { 66 | @apply block bg-transparent p-0 overflow-visible rounded-none; 67 | } 68 | 69 | &.hljs { 70 | background-color: #1f2937; 71 | 72 | code { 73 | @apply leading-loose; 74 | } 75 | } 76 | } 77 | 78 | ul { 79 | @apply text-base pl-8 list-disc; 80 | } 81 | 82 | ol { 83 | @apply text-base pl-8 list-decimal; 84 | } 85 | 86 | kbd { 87 | @apply text-xs inline-block rounded border px-1 py-1 align-middle font-normal font-mono shadow; 88 | } 89 | 90 | // Table 91 | table { 92 | @apply text-base border-gray-600; 93 | th { 94 | @apply border py-1 px-3; 95 | } 96 | td { 97 | @apply border py-1 px-3; 98 | } 99 | } 100 | 101 | .highlight pre { 102 | @apply bg-gray-100; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /assets/styles/app.scss: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | html { 7 | @apply scroll-smooth; 8 | } 9 | body { 10 | @apply font-KohinoorBangla; 11 | @apply text-dark; 12 | @apply bg-white dark:bg-slate-900; 13 | } 14 | a { 15 | @apply text-primary; 16 | } 17 | 18 | *::selection { 19 | @apply bg-primary text-gray-800; 20 | } 21 | ::-webkit-scrollbar { 22 | width: 3px; 23 | } 24 | 25 | ::-webkit-scrollbar-track { 26 | @apply bg-transparent; 27 | } 28 | 29 | ::-webkit-scrollbar-thumb { 30 | @apply bg-gray-600 rounded-lg; 31 | } 32 | } 33 | 34 | @layer utilities { 35 | .text-gradient { 36 | background-clip: text; 37 | -webkit-text-fill-color: transparent; 38 | } 39 | .wrapper { 40 | max-width: 1300px; 41 | width: 98%; 42 | margin: auto; 43 | position: relative; 44 | } 45 | 46 | // ### Theme------------------------- 47 | .app-border-color { 48 | @apply border-slate-200 dark:border-slate-600; 49 | } 50 | .app-icon-color { 51 | } 52 | 53 | .app-text-color { 54 | } 55 | 56 | // .app-button{ 57 | // @apply 58 | // } 59 | 60 | .text-dark { 61 | @apply text-slate-900 dark:text-slate-200; 62 | } 63 | .text-dark-secondary { 64 | @apply text-slate-600 dark:text-slate-300; 65 | } 66 | .text-dark-tertiary { 67 | @apply text-slate-400 dark:text-gray-600; 68 | } 69 | 70 | .bg-dark { 71 | @apply bg-gray-900 dark:bg-gray-200; 72 | } 73 | .bg-dark-secondary { 74 | @apply bg-gray-600 dark:bg-gray-300; 75 | } 76 | .bg-dark-tertiary { 77 | @apply bg-gray-100 dark:bg-gray-600; 78 | } 79 | 80 | .debug { 81 | position: relative; 82 | &::before { 83 | content: ""; 84 | position: absolute; 85 | width: 100%; 86 | height: 100%; 87 | top: 0; 88 | left: 0; 89 | border: 5px solid transparent; 90 | animation: blink 1000ms; 91 | animation-iteration-count: infinite; 92 | } 93 | } 94 | } 95 | 96 | @keyframes blink { 97 | 50% { 98 | border-color: #ff0000; 99 | } 100 | } 101 | 102 | .swal-footer { 103 | background-color: rgb(245, 248, 250); 104 | margin-top: 32px; 105 | border-top: 1px solid #e9eef1; 106 | overflow: hidden; 107 | } 108 | @import "base"; 109 | @import "content-typography"; 110 | @import "markdown"; 111 | @import "editor"; 112 | @import "loader"; 113 | @import "fonts"; 114 | @import "loader"; 115 | 116 | .top-full { 117 | top: 100%; 118 | } 119 | 120 | .ce-block--selected .ce-block__content { 121 | @apply dark:bg-gray-800; 122 | } 123 | 124 | 125 | .v-note-wrapper.shadow{ 126 | z-index: -10; 127 | } 128 | -------------------------------------------------------------------------------- /components/Alert.vue: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /components/Loader.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 45 | -------------------------------------------------------------------------------- /components/Logos/Dark.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /components/Logos/Text.vue: -------------------------------------------------------------------------------- 1 | 46 | -------------------------------------------------------------------------------- /components/Navbar/Navbar.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 64 | 65 | 80 | -------------------------------------------------------------------------------- /components/Navbar/SearchInput.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 103 | 104 | 111 | 146 | -------------------------------------------------------------------------------- /components/SlideOverSidebar.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 59 | 60 | 70 | -------------------------------------------------------------------------------- /components/app-image.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 46 | 47 | 52 | -------------------------------------------------------------------------------- /components/article-editor/md.vue: -------------------------------------------------------------------------------- 1 | 17 | 97 | 98 | 121 | -------------------------------------------------------------------------------- /components/article-editor/ribbon.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 42 | -------------------------------------------------------------------------------- /components/article-editor/thumbnail.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 102 | -------------------------------------------------------------------------------- /components/comments/editor.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 72 | -------------------------------------------------------------------------------- /components/comments/index.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 94 | -------------------------------------------------------------------------------- /components/contest-banner.vue: -------------------------------------------------------------------------------- 1 | 48 | 57 | 68 | -------------------------------------------------------------------------------- /components/contest-guideline-pages.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 49 | -------------------------------------------------------------------------------- /components/count-down-wrapper.vue: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /components/count-down.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 38 | 39 | 74 | 75 | 84 | -------------------------------------------------------------------------------- /components/dashboard/profile-info.vue: -------------------------------------------------------------------------------- 1 | 90 | 132 | -------------------------------------------------------------------------------- /components/dashboard/profile-photo.vue: -------------------------------------------------------------------------------- 1 | 81 | 82 | 137 | -------------------------------------------------------------------------------- /components/dashboard/profile-readme.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 59 | -------------------------------------------------------------------------------- /components/dashboard/profile-social.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 88 | -------------------------------------------------------------------------------- /components/dashboard/profile-tabs.vue: -------------------------------------------------------------------------------- 1 | 39 | 53 | 85 | -------------------------------------------------------------------------------- /components/form/button.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 40 | 41 | 54 | -------------------------------------------------------------------------------- /components/form/copyable.vue: -------------------------------------------------------------------------------- 1 | 24 | 50 | -------------------------------------------------------------------------------- /components/form/file-uploader.vue: -------------------------------------------------------------------------------- 1 | 55 | 56 | 99 | -------------------------------------------------------------------------------- /components/form/input.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 69 | 70 | 82 | -------------------------------------------------------------------------------- /components/form/textarea.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 110 | 111 | 127 | 128 | 126 | -------------------------------------------------------------------------------- /components/sidebar-left.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /components/sidebar-right.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /components/user-info-card.vue: -------------------------------------------------------------------------------- 1 | 106 | 107 | 117 | -------------------------------------------------------------------------------- /components/vote-wrapper.vue: -------------------------------------------------------------------------------- 1 | 120 | -------------------------------------------------------------------------------- /components/widgets/action-links.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 86 | 87 | 108 | -------------------------------------------------------------------------------- /components/widgets/discord.vue: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /components/widgets/fake-editor.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 38 | 39 | 57 | -------------------------------------------------------------------------------- /components/widgets/latest-registered-users.vue: -------------------------------------------------------------------------------- 1 | 40 | 53 | -------------------------------------------------------------------------------- /components/widgets/links.vue: -------------------------------------------------------------------------------- 1 | 46 | -------------------------------------------------------------------------------- /components/widgets/login-buttons.vue: -------------------------------------------------------------------------------- 1 | 103 | 104 | 126 | 127 | 164 | -------------------------------------------------------------------------------- /components/widgets/login.vue: -------------------------------------------------------------------------------- 1 | 33 | -------------------------------------------------------------------------------- /components/widgets/sponsor.vue: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /components/widgets/top-writters.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 27 | 28 | 78 | -------------------------------------------------------------------------------- /components/widgets/vuejs-bootcamp.vue: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /content/_contest/guides/writing-tricks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ব্লগ লিখার কিছু টিপস এন্ড ট্রিক্স 3 | slug: writing-tricks 4 | --- 5 | 6 | > কন্টেন্ট গুলো অভিযাত্রী থেকে সংগৃহীত 7 | 8 | ![](https://cdn.statically.io/img/www.projuktiravijatri.com/f=auto/wp-content/uploads/2017/12/Successful-blog-post.png) 9 | 10 | একটি সফল ব্লগ পোষ্ট লেখার জন্য কি কি বিষয় জানা প্রয়োজন ও এর সাথে কিছু কার্যকরী টিপস নিয়ে অভিযাত্রিদের উদ্দেশ্যে এই লেখাটি একজন সফল লেখক হতে সাহায্য করবে। 11 | 12 | যারা নতুন লেখালিখি শুরু করছে, তাদের মধ্যে বেশীরভাগই কোনো গাইডলাইন ছাড়া এলোমেলো ভাবে ব্লগ লেখে। মাথায় একটা আইডিয়া আসলো আর ওমনি লেখা শুরু করে দিলো। যারা ফলে অসংখ্য লেখা পাওয়া যায় কিন্তু গুণগতমান সম্পন্ন লেখা খুঁজে পাওয়া কষ্টকর। একটি সুন্দর ও আকর্ষনীয় ব্লগ লেখার মধ্যে যেমন অন্যরকম আনন্দ পাওয়া যায় তেমনি ভাবে এখানে শেখারও অনেক কিছু রয়েছে। নির্দিষ্ট একটি বিষয়ে লেখা শুরু করার আগে ফর্মুলা মেনে চললেই কিন্তু অসাধারণ লেখা উপস্থাপন করা যায়। 13 | 14 | তাই আজকের এই লেখায় আমি শেয়ার করবো কিভাবে লেখার ফর্মূলা মেনে পাঠকদের ভালো ব্লগ উপহার দেওয়া যায়! তার আগে জেনে নেওয়া যাক একটি আদর্শ ব্লগের কি কি অংশ রয়েছে? 15 | 16 | যেকোনো ব্লগেরই কয়েকটা পার্ট বা অংশ থাকে, যার প্রতিটাই গুরুত্বপূর্ণ। আমি ৭টি অংশে একটি ব্লগ পোষ্টকে ব্যবচ্ছেদ করলাম। 17 | 18 | ১। **টাইটেল বা শিরোনাম** **–** ব্লগের যেই অংশটি সর্বপ্রথম পাঠকদের দৃষ্টি আকর্ষণ করে সেটি হচ্ছে শিরোনাম। এটি যত বেশী আকর্ষণীয় করে তোলা যাবে সেই ব্লগটি তত বেশী পাঠকদের পড়তে বাধ্য করবে। ব্লগের শিরোনাম যদি ৮ সেকেন্ডের মতো পাঠককে ধরে রাখতে পারে তাহলে ধরে নেওয়া যায় ব্লগ লেখা সার্থক। তাই অস্থির শিরোনাম লেখার জন্য মনোযোগ দেওয়া উচিত। 19 | 20 | ২। **শুরুতে কিছু কথা বা সূচনা –** শিরোনামের পরেই ব্লগের ২য় গুরুত্বপূর্ণ অংশটি হচ্ছে এটি। যেহেতু শিরোনামে অনেক অল্প সময়ের মধ্যে পাঠক সিদ্ধান্ত নিয়ে ফেলেছে সে পুরো লেখাটি পড়বে তাই এই অংশে সংক্ষিপ্তভাবে পুরো লেখাটিতে কি কি রয়েছে তা বলে দিতে হবে। বিভিন্ন উপায়ে ভুমিকা দেওয়া যেতে পারে যেমন, গল্প-আকারে, কোনো প্রশ্ন জিজ্ঞাসা করে, বর্তমান সময়ের কোনো ঘটনার উল্লেখ করে অথবা কৌতুক দিয়েও শুরু করা যেতে পারে। 21 | 22 | যেভাবেই শুরু হোক না কেনো মনে রাখতে হবে এই অংশ পড়ার সময় যাতে পাঠককের আগ্রহ সৃষ্টি হয় এবং সে সামনে অগ্রসর হয়। আমি এখানে সাজেস্ট করবো লেখক এই অংশে এমন কিছু মজার, চমকপ্রদ তথ্য দিবে যা টপিক রিসার্চের সময় তার ভালো লেগেছে। 23 | 24 | ৩। **মূল লেখা –** এখানে বিশদ আকারে লিখার ক্ষেত্রে মনে রাখার বিষয় হচ্ছে, লিস্ট-বুলেট আকারে, নাম্বার দিয়ে সাজিয়ে, উদ্ধৃতি দিয়ে লেখাকে সহজ ও সাবলিল ভাবে উপস্থাপন করতে হবে যাতে পাঠকের বিষয়টি বুঝতে ও মনে রাখতে সুবিধা হয়। 25 | 26 | ৪। **উপ-শিরোনাম বা সাবটাইটেল –** কনটেন্ট সম্পর্কে পূর্ণ ধারণা দেওয়া ও লেখার গঠনকে পাঠকের সামনে তুলে ধরার জন্য সাবটাইটেলের গুরুত্ব রয়েছে। এটি এমন ভাবে কনটেন্টে যোগ করতে হবে যাতে যে কেউ পুরো লেখাটিতে একবার নজর রাখলেই বুঝতে পারে, কি কি বিষয়ে আলোচনা করা হয়েছে। 27 | 28 | ৫। **প্রাসঙ্গিক ছবি –** অসংখ্য লেখাকে একটি ছবির মধ্য দিয়ে প্রকাশ করা যায়। তারমধ্যে সেই ছবিতে যদি অল্প কিছু লিখে (ক্যাপশন) দেওয়া যায় তাহলে তো কথাই নেই। পাঠকদের দ্রুত বোঝার সুবিধার্থে, ছবির ক্যাপশন গুলো অবশ্যই শিরোনাম, উপ-শিরোনামের মতো আকর্ষনীয় করে তুলতে হবে। 29 | 30 | ৬। **ফিচার ইমেজ –** ব্লগের লেখাটি কি বিষয়ে তারই একটি প্রতিফলন হচ্ছে ফিচার ইমেজ, এটি ব্লগে পাঠকদের নিয়ে আসতে একটি অর্থবহ ভূমিকা রাখে। 31 | 32 | ৭। **আইডিয়া বা টপিক নির্বাচন –** লেখা শুরু করার আগে এই বিষয়টিই সবচেয়ে গুরুত্বপূর্ণ। আইডিয়া বের করার ক্ষেত্রে আমি শুধু বলবো, এমন টপিক বাছাই করবেন যে বিষয়ে আপনি ভালো জানেন এবং অন্যদেরকে ভালো ভাবে বোঝাতে পারবেন বলে মনে করেন। 33 | 34 | ৮। **রিসার্চ –** আপনি যেই বিষয় নিয়েই লিখুন না কেনো, সবসময় চেষ্টা করবেন, যেই বিষয়টি নিয়ে লিখতে যাচ্ছেন সেটির অনেক গভীরে যাওয়ার। অধিকাংশ লেখকই টপিক নির্বাচন করার পর সেই বিষয়ে গুগলিং করে যতটুকু সম্ভব অন্যান্য লেখা পড়ে থাকে। সংগ্রহ করা রিসোর্স গুলোকে একটি লিস্ট আকারে তৈরী করা যেতে পারে। 35 | 36 | ৯। **প্ল্যান –** এখন লেখাটির একটি স্ট্রাকচার তৈরী করার সময়। এসময় আমি প্ল্যানিং করে পুরো ব্লগটার একটি গঠন প্রস্তুত করি। যেখানে লেখাটির কনটেন্ট আমার মাথায় থাকে আর সেই অনুযায়ী শিরোনাম, উপ-শিরোনাম ও অন্যান্য বিষয়সমূহ নির্দিষ্ট করে ফেলি। উদাহরণ হিসেবে বলা যায়, এখন যে লেখাটি পড়ছেন তার মূল পয়েন্ট গুলো আমি প্ল্যানিং করার সময় তৈরী করেছি। 37 | 38 | ১০। **লক্ষ্য –** ব্লগের টপিকের উপর ভিত্তি করে লেখাটি কতো শব্দের মধ্যে শেষ করা যায় সেটি নির্ধারণ করা। সাধারণত অনলাইন পাঠকরা ১০০০-২০০০ শব্দের লেখা পড়তে বেশী স্বাচ্ছন্দ্যবোধ করে। 39 | 40 | ১১। **পরিসংখ্যান যোগ করা –** যতটুকু সম্ভব বিভিন্ন তথ্য-উপাত্তের উপর ভিত্তি করে লেখাটি পূর্ণাঙ্গ করা। বিভিন্ন পরিসংখ্যান ও অনুমোদিত তথ্য যোগ করলে লেখাটিকে অনেক প্রাণবন্ত মনে হবে, যেটি পাঠকের কাছে ভালো লাগা তৈরী করবে। 41 | 42 | ১২। **সম্পৃক্ত লেখা যুক্ত করা –** যতটুকু সম্ভব অন্যান্য পোষ্টের সাথে যোগসূত্র তৈরী করা। এর মানে এই না যে পাঠককে ব্লগের অন্য লেখা পড়তে উৎসাহিত করছেন। বরং অন্য লেখা সংযোগ করলে ঐ বিষয়ে নতুন করে বিস্তারিত আর বলতে হয়না। অতিরিক্ত লেখা সাশ্রয় হয়। 43 | 44 | ১৩। **শেষকথা –** পরিশেষে পুরো ব্লগে যেসব বিষয়ে আলোচনা করা হয়েছে তার একটি সংক্ষিপ্ত উপসংহার উপস্থাপন করতে হবে। এই অংশে চাইলে লেখায় ব্যবহৃত বিভিন্ন রিসোর্স, লিঙ্ক দেওয়া যেতে পারে। 45 | -------------------------------------------------------------------------------- /content/_contest/guides/writting-guidelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: লেখক এর জন্য কিছু নির্দেশনা 3 | slug: writting-guidelines 4 | --- 5 | 6 | > রুলস গুলো ঠিক মত আপনি বিজয়ী হইয়ার ক্ষেত্রে অন্যদের চেয়ে অনেক এগিয়ে থাকবেন। আপনি যদি একাধিক আর্টিকেল লিখতে পারেন, তাহলে আপনি অন্য লেখকদের থেকে এগিয়ে থাকবেন ! 7 | 8 | ### তথ্য সংগ্রহের নিতিমালা 9 | 10 | - তথ্যের উৎসের ব্যাপারে সতর্ক থাকতে হবে। অনির্ভরযোগ্য উৎস থেকে প্রাপ্ত তথ্য ব্যবহার করার অনুমতি দেয়া হবে না। ব্যবহার করা সব তথ্য বিশ্বাসযোগ্য হতে হবে। যদি কোনো ওয়েবসাইট থেকে তথ্য নেয়া হয় তাহলে নিবন্ধের শেষে পুরো URL লিখে দিতে হবে (footnote ১, ২, ৩... এভাবে) অথবা সুবিধামতো হাইপারলিংক করে দিতে হবে। 11 | 12 | - কোনো বই থেকে তথ্য নেয়া হলে প্রয়োজনীয় জায়গায় বুকমার্ক দিতে হবে। আর্টিকেলের শেষে নিচে বর্ণিত বিন্যাসে বইটি উদ্ধৃত করতে হবে: 13 | - বইয়ের নাম: 14 | - লেখক এর নাম: 15 | - পৃষ্ঠা নম্বর: 16 | - সংস্করণ নম্বর: 17 | - প্রকাশক: 18 | - প্রকাশনার তারিখ: 19 | 20 | ### ছবি সংক্রান্ত নির্দেশনা 21 | 22 | ছবিগুলোতে কোনো ধরনের জলছাপ(watermark) থাকা চলবে না। কোনো প্রকারের নগ্ন বা অশ্লীল ছবি(nudes ছবি) বা ভিডিও(video) কোনোভাবেই গ্রহণযোগ্য হবে না। সম্ভব হলে অবশ্যই চিত্রগ্রাহকের নাম ছবির ক্যাপসন উল্লেখ করতে হবে। সম্ভব হলে অবশ্যই যে ওয়েবসাইট থেকে ছবি নেয়া হয়েছে তার নাম ছবির ক্যাপসনে উল্লেখ করার অনুরোধ জানানো হচ্ছে। 23 | 24 | ![](https://res.cloudinary.com/techdiary-dev/image/upload/v1619441481/static-assets/static-page-images/image-caption.png) 25 | 26 | ফিচার ইমেজের প্রস্থ কমপক্ষে ১,২০০X ৬৩০ পিক্সেল হতে হবে, অন্যথায় আর্টিকেল যখন ফেসবুকে শেয়ার করবেন সেটি ঠিক মত দেখাবে না। 27 | 28 | ### লিখন শেয়ার ও অন্য কোন মাধ্যমে শেয়ার এর বিধিমালা 29 | 30 | আর্টিক্যাল লিখে অবশ্যই আপানর সোশ্যাল মিডিয়া প্রোফাইল গুলিতে শেয়ার হ্যাশট্যাগ সহ (#techdiary_contest_2 #devshopbd) শেয়ার করতে হবে এবং [টেকডায়েরির ফেসবুক পেজ](https://www.fb.com/techdiary.dev) এবং [ডেভশপ বিডি ফেসবুক পেজ](https://www.fb.com/devshopbd) এ লাইক দেয়া থাকতে হবে। 31 | 32 | বিজয়ী ঘোষণা করা হবে আর্টিক্যাল এর Upvote এবং আর্টিক্যালের কোয়ালিটির উপর ভিত্তি করে। বিভিন্ন গ্রুপে এবং আপনার প্রোফাইলে আপনি যত বেশি শেয়ার করবেন আপনার আপভোট পাওয়ার এবং বিজয়ী হওয়ার সম্ভাবনা তত বেড়ে যাবে। 33 | 34 | ### কন্টেস্ট জন্যে আর্টিকেল জমাদানের নীতিমালা 35 | 36 | এখানে আপনার ইচ্ছামত সকল ধরনের আর্টিকেল লিখতে পারেন তবে আপনি যদি কন্টেস্ট এ অংশ গ্রহন করতে চান তাহলে অবশ্যই আপনাকে `contest_season_2` এবং `devshopbd` ট্যাগটি যুক্ত করতে হবে এবং উপরোক্ত নিয়ম ফলো করে আপনাকে আর্টিকেল সাবমিশন করতে হবে! 37 | 38 | আর্টিক্যাল এর সেটিং প্যানেল থেকে আপনি ট্যাগ সংযুক্ত অপশন পাবেন। 39 | 40 | ![](https://res.cloudinary.com/techdiary-dev/image/upload/v1643533021/static-assets/contest/gooyxrg8mgytcjk3an4x.png) 41 | 42 | ![](https://res.cloudinary.com/techdiary-dev/image/upload/v1643532608/static-assets/contest/qaasu23jiqxeqznk81db.png) 43 | -------------------------------------------------------------------------------- /content/_contest/welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rules of Contest 3 | slug: rules 4 | thumbnail: https://res.cloudinary.com/techdiary-dev/image/upload/v1643557917/static-pages-assets/graphland.dev_gmail.com_bgg5zr.png 5 | --- 6 | 7 | > লেখার বিষয়সমূহ আপনি প্রযুক্তি, প্রোগ্রামিং, ডেভলপমেন্ট এবং সফটওয়্যার ইঞ্জিনিয়ারিং অথবা প্রযুক্তি কল্পকাহিনি (Sci-fi) নিয়ে লিখতে পারবেন। 8 | 9 | **প্রাইস** 10 | 11 | - ১০ টি ডেভেলপার টি-শার্ট 12 | - ১০ টি ডেভেলপার স্টিকার প্যাক 13 | 14 | **প্রাইস পাওয়ার ক্ষেত্রে শর্তাবলী** 15 | 16 | - প্রাইস পাওয়ার জন্য আপনাকে [টেকডায়েরির ফেজবুক পেজ](https://www.facebook.com/techdiary.dev) এবং [ডেভশপ বিডির ফেসবুক পেজ](https://www.facebook.com/devshopbd) লাইক দিতে হবে। 17 | - উল্লেখিত ক্যাটাগরির কমপক্ষে চারটি টি ব্লগ লিখতে হবে। আর্টিক্যাল গুলো মিনিমাম ৫০০ ওয়ার্ড হলে পুরষ্কার পাওয়ার ক্ষেত্রে আপনি এগিয়ে থাকবেন। 18 | - আর্টিক্যাল সোস্যাল মিডিয়ায় শেয়ার করতে হবে। 19 | - সোস্যাল মিডিয়ায় শেয়ার করার সময় দুটি হ্যাশট্যাগ [#techdiary_contest_2](https://www.facebook.com/hashtag/techdiary_contest_2) এবং [#devshopbd](https://www.facebook.com/hashtag/devshopbd) ব্যবহার করতে হবে। 20 | - কন্টেন্টটি আপনার কোনক্রমে অন্য কোন কন্টেন্ট এর সাথে ৭০ থেকে ৮০ ভাগ এবং এর বেশি মিল পাওয়া গেলে, আপনার কন্টেন্ট এবং আপনাকে কনটেস্ট হতে বহিষ্কার করা হবে। 21 | - সবচেয়ে ভালো হয় সাম্প্রতিক সময়ে আপনি যেসব টেকনোলজি বা পোগ্রামিং নিয়ে কাজ করেছেন। সেসব নিয়ে ব্লগ লিখতে আমরা উৎসাহিত করি। 22 | - আর্টিক্যাল এর কোয়ালিটি, পরিমাণ(আপনি কয়টি আর্টিক্যাল সাবমিট করেছেন কনটেস্টের জন্যে) এবং আপভোটের উপর নির্ভর করে ১০জন বিজয়ী নির্ধারন করা হবে। 23 | - কনটেস্টের জন্যে আর্টিক্যাল জমা দেওয়ার শেষ সময় ২৮ ফেব্রুয়ারী রাত ১১ঃ৫৯ মিনিট। এই সময়ের পরের সাবমিটকৃত আর্টিক্যাল কনটেস্টের আওতায় ধরা হবে না। 24 | - পুরষ্কার পেতে ১০-১৫ দিন পর্যন্ত সময় লাগতে পারে। 25 | - পুরষ্কার প্রদান করার ক্ষেত্রে টেকডায়েরি এবং ডেভশপ বিডির সিদ্ধান্তই চূড়ান্ত সিদ্ধান্ত হিসেবে বিবেচিত হবে। 26 | -------------------------------------------------------------------------------- /content/_pages/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: আমাদের সম্পর্কে 3 | slug: about 4 | --- 5 | 6 | ## এখনো লিখা হয়নি 7 | -------------------------------------------------------------------------------- /content/_pages/md-demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: টাইপগ্রাফি নমুনা 3 | slug: typography-demo 4 | --- 5 | 6 | # হেডিং ১ 7 | 8 | ## হেডিং ২ 9 | 10 | ### হেডিং ৩ 11 | 12 | ##### হেডিং ৪ 13 | 14 | ###### হেডিং ৫ 15 | 16 | ###### হেডিং ৬ 17 | 18 | অর্থহীন লেখা যার মাঝে আছে অনেক কিছু। হ্যাঁ, এই লেখার মাঝেই আছে অনেক কিছু। যদি তুমি মনে করো, এটা তোমার কাজে লাগবে, তাহলে তা লাগবে কাজে। নিজের ভাষায় লেখা দেখতে অভ্যস্ত হও। মনে রাখবে লেখা অর্থহীন হয়, যখন তুমি তাকে অর্থহীন মনে করো; আর লেখা অর্থবোধকতা তৈরি করে, যখন তুমি তাতে অর্থ ঢালো। যেকোনো লেখাই তোমার কাছে অর্থবোধকতা তৈরি করতে পারে, যদি তুমি সেখানে অর্থদ্যোতনা দেখতে পাও। …ছিদ্রান্বেষণ? না, তা হবে কেন? 19 | 20 | ## তালিকা 21 | 22 | - অর্থহীন লেখা যার মাঝে আছে 23 | - অর্থহীন লেখা যার মাঝে আছে 24 | - অর্থহীন লেখা যার মাঝে আছে 25 | - অর্থহীন লেখা যার মাঝে আছে 26 | - অর্থহীন লেখা যার মাঝে আছে 27 | - অর্থহীন লেখা যার মাঝে আছে 28 | - অর্থহীন লেখা যার মাঝে আছে 29 | 30 | ## নম্বরযুক্ত তালিকা 31 | 32 | 1. অর্থহীন লেখা যার মাঝে আছে 33 | 2. অর্থহীন লেখা যার মাঝে আছে 34 | 3. অর্থহীন লেখা যার মাঝে আছে 35 | 4. অর্থহীন লেখা যার মাঝে আছে 36 | 5. অর্থহীন লেখা যার মাঝে আছে 37 | 6. অর্থহীন লেখা যার মাঝে আছে 38 | 7. অর্থহীন লেখা যার মাঝে আছে 39 | 40 | If you want to embed images, this is how you do it: 41 | 42 | ![Image of Yaktocat](https://octodex.github.com/images/yaktocat.png) 43 | 44 | _এই পাঠ্যটি তাত্ক্ষণিক_ 45 | _এটিও ইটালিক_ 46 | 47 | **এই পাঠ্য সাহসী হবে** 48 | **এটি সাহসীও হবে** 49 | 50 | _আপনি **তাদের** একত্রিত করতে পারেন_ 51 | 52 | ### সিনট্যাক্স হাইলাইট করা 53 | 54 | ```javascript 55 | function fancyAlert(arg) { 56 | if (arg) { 57 | $.facebox({ div: "#foo" }); 58 | } 59 | } 60 | ``` 61 | 62 | ### কার্য তালিকাগুলি 63 | 64 | - [x] @mentions, #refs, [links](), **formatting**, and tags supported 65 | - [x] list syntax required (any unordered or ordered list supported) 66 | - [x] this is a complete item 67 | - [ ] this is an incomplete item 68 | 69 | যদি আপনি কোনও সমস্যার প্রথম মন্তব্যে কোনও কার্য তালিকা অন্তর্ভুক্ত করেন তবে আপনি আপনার ইস্যু তালিকায় একটি কার্যকর অগ্রগতি সূচক পাবেন। এটি পুল অনুরোধেও কাজ করে! 70 | 71 | ### টেবিল 72 | 73 | | First Header | Second Header | 74 | | --------------------------- | ---------------------------- | 75 | | Content from cell 1 | Content from cell 2 | 76 | | Content in the first column | Content in the second column | 77 | -------------------------------------------------------------------------------- /content/_pages/terms-and-conditions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ব্যবহারবিধি এবং নীতিমালা (Terms and conditions) 3 | slug: terms-and-conditions 4 | --- 5 | 6 | টেক ডাইরি একটি অলাভজনক প্রোগ্রামিং ব্লগিং সাইট, আমাদের সাইট ব্যবহার এর জন্য আপনাকে আমাদের শর্তাদি মেনে নিতে হবে। 7 | 8 | > টেক ডাইরিতে আপনি লিখার আগে আপনাকে মনে রাখতে হবে লিখাটি অবশ্যই আপনার । 9 | 10 | ## টেক ডাইরি ব্যাবহারের কিছু দিক নির্দেশনা: 11 | 12 | ### লেখার বিষয়বস্তু এবং আপনি যেসব বিষয় নিয়ে লিখতে পারবেন 13 | 14 | লেখার বিষয়সমূহ আপনি প্রযুক্তি, প্রোগ্রামিং, ডেভলপমেন্ট এবং সফটওয়্যার ইঞ্জিনিয়ারিং অথবা প্রযুক্তি কল্পকাহিনি(science fiction) নিয়ে লিখতে পারবেন। 15 |
16 | 17 | ### তথ্য সংগ্রহের নিতিমালা 18 | 19 | তথ্যের উৎসের ব্যাপারে সতর্ক থাকতে হবে। অনির্ভরযোগ্য উৎস থেকে প্রাপ্ত তথ্য ব্যবহার করার অনুমতি দেয়া হবে না। ব্যবহার করা সব তথ্য বিশ্বাসযোগ্য হতে হবে। যদি- কোনো ওয়েবসাইট থেকে তথ্য নেয়া হয় তাহলে নিবন্ধের শেষে পুরো URL লিখে দিতে হবে (বুকমার্ক ১, ২, ৩... এভাবে) অথবা সুবিধামতো হাইপারলিংক করে দিতে হবে। 20 | কোনো বই থেকে তথ্য নেয়া হলে প্রয়োজনীয় জায়গায় বুকমার্ক দিতে হবে। নিবন্ধের শেষে নিচে বর্ণিত বিন্যাসে বইটি উদ্ধৃত করতে হবে– 21 | 22 | - বইয়ের নাম: 23 | - লেখক এর নাম: 24 | - পৃষ্ঠা নম্বর: 25 | - সংস্করণ নম্বর: 26 | - প্রকাশক: 27 | - প্রকাশনার তারিখ: 28 |
29 | 30 | ### লেখক হতে আমাদের প্রত্যাশা 31 | 32 | আমাদের প্রত্যাশা আপনার লিখনটি এমনভাবে সাজাতে হবে যাতে মনে হয় আপনি আপনার সামনে বসে থাকা পাঠকদের বিষয়বস্তু শোনাচ্ছেন এবং লেখক চেষ্টা বিষয় গুলো যথেষ্ট সুন্দর সাবলীল ভাবে ব্যখ্যা করা যায় এবং লেখক সুন্দরভাবে বোঝনোর উদ্যেশ্যে প্রয়োজনীয় ছবি এবং উদাহরণ কোড ব্যবহার করবেন। লিখনটি কমপক্ষে ৭৫০ শব্দের মধ্যে থাকা আদর্শ লিখন। তবে কোনো সর্বনিন্ম শব্দ সীমা নেই। 33 |
34 | 35 | ### ছবি সংক্রান্ত নির্দেশনা 36 | 37 | ছবিগুলোতে কোনো ধরনের জলছাপ(watermark) থাকা চলবে না। কোনো প্রকারের নগ্ন বা অশ্লীল ছবি(nudes ছবি) বা ভিডিও(video) কোনোভাবেই গ্রহণযোগ্য হবে না। সম্ভব হলে অবশ্যই চিত্রগ্রাহকের নাম ছবির ক্যপশনে উল্লেখ করতে হবে। সম্ভব হলে অবশ্যই যে ওয়েবসাইট থেকে ছবি নেয়া হয়েছে তার নাম ছবির ক্যাপশনে উল্লেখ করার অনুরোধ জানানো হচ্ছে। 38 | 39 | ফিচার ইমেজের আকারফিচার ইমেজের প্রস্থ কমপক্ষে ১,২০০X ৬৩০ পিক্সেল হতে হবে। অন্যথায় আর্টিক্যাল যখন ফেসবুকে শেয়ার করবেন সেটি ঠিক মত দেখাবে না। 40 |
41 | 42 | ### লিখন শেয়ার ও অন্য কোন মাধ্যমে শেয়ার এর বিধিমালা 43 | 44 | লিখক তার লিখা যেকোন মাধ্যমে শেয়ার করার সর্বোচ্চ স্বাধীনতা রয়েছে , এ ক্ষেত্রে টেক ডাইরি কোন হস্তক্ষেপ করবে নাহ! 45 | 46 |
47 | 48 | ## সাধারন ব্যবহারকারীর বিধিমালা 49 | 50 | - আপনি লিখিত আর্টিকেল গুলার যথার্থ মুল্যায়ন করবেন এবং সম্ভব হয়ে যৌক্তিক সমালোচনা করবেন তবে সমালোচনা যাতে একজন জ্ঞানীর মত হয় সেই দিক টা লক্ষ্য রাখবেন! 51 | - আপনি টেকডাইরির আর্টিকেল গুলা সরাসরি সাইট থেকে শেয়ার করতে পারবেন । লেখকের অনুমতি ছাড়া আপনি এগুলো কখনো কপি করতে পারবেন নাহ আর এমন যদি কেউ করে তাহলে সরাসরি তার টেক ডাইরির মেম্বারশিপ বাতিল করা হবে! 52 | - আপনি যদি বিশ্বাস করেন যে কোনও ব্যবহারকারী আপনার লিখিত ডায়েরি অনুমতি ছাড়া ব্যবহার করেছে, তাদের পরিচয় ভুলভাবে উপস্থাপন করেছে, দয়া করে [graphland.dev@gmail.com](mailto:graphland.dev@gmail.com?subject=techdiary.dev%3A%20article%20plagiarism%20complain) ইমেল করুন অথবা [ফেসবুক পেজ](https://www.facebook.com/techdiary.dev) এ সরাসরি আমাদের জানান । 53 | - আপনি যদি টেক ডাইরিতে কোন বাগ অথবা ব্যবহার করার সময় কোন সমস্যা অথবা আপনার কোন ধরনের অভিযোগ কিংবা কোন উপদেশ দিতে প্রয়োজন হয় আমদের মেইল করুন অথবা সরাসরি ফেসবুক পেইজ এ জানিয়ে দিন ! 54 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "~/*": ["./*"], 6 | "@/*": ["./*"], 7 | "~~/*": ["./*"], 8 | "@@/*": ["./*"] 9 | } 10 | }, 11 | "exclude": ["node_modules", ".nuxt", "dist"] 12 | } 13 | -------------------------------------------------------------------------------- /layouts/blank.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /layouts/dashboard.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 29 | 30 | 35 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /layouts/left-sidebar.vue: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /layouts/three-columns.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 53 | -------------------------------------------------------------------------------- /mixins/bookmark.js: -------------------------------------------------------------------------------- 1 | import swal from "sweetalert"; 2 | 3 | export default { 4 | methods: { 5 | bookmark(model_name, model_id) { 6 | if (!this.$auth.loggedIn) { 7 | swal({ 8 | title: "আপনি লগইন অবস্থায় নেই", 9 | icon: "error", 10 | }); 11 | return; 12 | } 13 | 14 | this.$axios.$post(`api/bookmarks`, { 15 | model_name, 16 | model_id, 17 | }); 18 | 19 | this.isBookmarked = !this.isBookmarked; 20 | }, 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /mixins/form-validation.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data() { 3 | return { 4 | errors: {}, 5 | }; 6 | }, 7 | methods: { 8 | catchValidationErrors(error) { 9 | if (error.response.status === 422) { 10 | this.errors = error.response.data.errors; 11 | } 12 | }, 13 | hasError(property) { 14 | return this.errors[property] !== undefined; 15 | }, 16 | hasErrorMessage(property) { 17 | if (!Object.keys(this.errors).length) return ""; 18 | 19 | return ( 20 | Object.keys(this.errors).length && 21 | this.errors[property] && 22 | this.errors[property].join("") 23 | ); 24 | }, 25 | yupToFormErrors(yupError) { 26 | let errors = {}; 27 | if (yupError.inner) { 28 | for (let err of yupError.inner) { 29 | if (!errors[err.path]) { 30 | errors[err.path] = err.errors; 31 | } 32 | } 33 | } 34 | return errors; 35 | }, 36 | 37 | jsonToPlainErrorText(errors) { 38 | let err = ""; 39 | for (let key in errors) { 40 | err += " " + errors[key].join(". "); 41 | } 42 | return err; 43 | }, 44 | cleanupFormObject(formObject) { 45 | const cleanedFormObject = {}; 46 | Object.keys(formObject).forEach((key) => { 47 | if (formObject[key] !== "") { 48 | cleanedFormObject[key] = formObject[key]; 49 | } 50 | }); 51 | return cleanedFormObject; 52 | }, 53 | }, 54 | }; 55 | -------------------------------------------------------------------------------- /mixins/reactions.js: -------------------------------------------------------------------------------- 1 | import bnNum from "bnnum"; 2 | 3 | export default { 4 | methods: { 5 | reactedByMe(reaction_type) { 6 | if (!this.$auth.loggedIn) return false; 7 | return ( 8 | this.reactions && 9 | this.reactions[reaction_type] && 10 | this.reactions[reaction_type].reactors.includes(this.$auth.user.id) 11 | ); 12 | }, 13 | async doReact(reaction_type, article_slug) { 14 | if (!this.$auth.loggedIn) { 15 | this.$store.commit("alert/ERROR_ALERT", "আপনি লগইন অবস্থায় নেই"); 16 | return; 17 | } 18 | 19 | if (!this.reactions || !this.reactions.hasOwnProperty(reaction_type)) { 20 | let reactions = { 21 | [reaction_type]: { 22 | count: 0, 23 | reactors: [] 24 | } 25 | }; 26 | this.reactions = { ...reactions, ...this.reactions }; 27 | } 28 | 29 | if (this.reactions[reaction_type].reactors.includes(this.$auth.user.id)) { 30 | // remove me from reactors and decrement count 31 | --this.reactions[reaction_type].count; 32 | this.reactions[reaction_type].reactors = this.reactions[ 33 | reaction_type 34 | ].reactors.filter(uid => uid !== this.$auth.user.id); 35 | } else { 36 | // add me from reactors and increment count 37 | ++this.reactions[reaction_type].count; 38 | this.reactions[reaction_type].reactors.push(this.$auth.user.id); 39 | } 40 | 41 | const { reactions } = await this.$axios.$post( 42 | `api/articles/${article_slug}/reaction`, 43 | { 44 | reaction_type 45 | } 46 | ); 47 | 48 | this.reactions = reactions; 49 | }, 50 | 51 | reactionCount(reaction_type) { 52 | if (this.reactions && reaction_type in this.reactions) { 53 | return bnNum(this.reactions[reaction_type].count, true); 54 | } 55 | 56 | return bnNum(0); 57 | } 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /mixins/share.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | copyToClipboard(text, prompt = "লিংক কপি করা হয়েছে") { 4 | if (navigator.clipboard) { 5 | navigator.clipboard.writeText(text); 6 | } else { 7 | const textArea = document.createElement("textarea"); 8 | textArea.value = text; 9 | document.body.appendChild(textArea); 10 | textArea.select(); 11 | document.execCommand("copy"); 12 | textArea.remove(); 13 | } 14 | 15 | this.$toast.success(prompt); 16 | }, 17 | shareOnFacebook(url) { 18 | window.open( 19 | "https://www.facebook.com/sharer/sharer.php?u=" + url, 20 | "pop", 21 | "width=600, height=400, scrollbars=no" 22 | ); 23 | }, 24 | shareOnTwitter(url) { 25 | window.open( 26 | "https://twitter.com/intent/tweet?text=Check%20out%20this%20article%20on%20the%20blog techdiary%20" + 27 | url, 28 | "pop", 29 | "width=600, height=400, scrollbars=no" 30 | ); 31 | }, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /mixins/social-login.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data() { 3 | return { 4 | loadingGithub: false, 5 | loadingGoogle: false, 6 | }; 7 | }, 8 | methods: { 9 | socialLogin(service) { 10 | if (service == "google") { 11 | this.loadingGoogle = true; 12 | } 13 | 14 | if (service == "github") { 15 | this.loadingGithub = true; 16 | } 17 | 18 | window.location.href = `${process.env.NUXT_ENV_API_URL}/api/oauth/${service}`; 19 | }, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /mixins/upload.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | /** 4 | * Upload file 5 | * @param {*} file 6 | * @param {*} preset 7 | * @returns 8 | */ 9 | async uploadFile(file, preset) { 10 | if (!file.type.startsWith("image/")) { 11 | throw new Error("Only image file is supported for upload"); 12 | } 13 | 14 | const fd = new FormData(); 15 | fd.append("preset", preset); 16 | fd.append("file", file); 17 | 18 | const res = await this.$axios.$post("api/files", fd); 19 | return res.url; 20 | }, 21 | async deleteFile(file_url) { 22 | await this.$axios.$delete("api/files", { data: { file_url } }); 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /mixins/votes.js: -------------------------------------------------------------------------------- 1 | import swal from "sweetalert"; 2 | 3 | export default { 4 | computed: { 5 | isUpvotted() { 6 | if (!this.$auth.loggedIn) return false; 7 | return this.votes?.up_voters?.includes(this.$auth.user.id); 8 | }, 9 | isDownvotted() { 10 | if (!this.$auth.loggedIn) return false; 11 | return this.votes?.down_voters?.includes(this.$auth.user.id); 12 | }, 13 | }, 14 | methods: { 15 | removeFromUpvotterList() { 16 | this.votes.up_voters = this.votes.up_voters.filter( 17 | (userId) => userId != this.$auth.user.id 18 | ); 19 | }, 20 | removeFromDownvotterList() { 21 | this.votes.down_voters = this.votes.down_voters.filter( 22 | (userId) => userId != this.$auth.user.id 23 | ); 24 | }, 25 | addToUpvoters() { 26 | this.votes.up_voters.push(this.$auth.user.id); 27 | }, 28 | addToDownvoters() { 29 | this.votes.down_voters.push(this.$auth.user.id); 30 | }, 31 | upVote(model_name, model_id) { 32 | if (!this.$auth.loggedIn) { 33 | swal({ 34 | title: "আপনি লগইন অবস্থায় নেই", 35 | icon: "error", 36 | }); 37 | return; 38 | } 39 | 40 | this.$axios.$post(`api/vote`, { 41 | model_name, 42 | model_id, 43 | vote: "UP_VOTE", 44 | }); 45 | 46 | if (this.isUpvotted) { 47 | this.removeFromUpvotterList(); 48 | this.votes.score--; 49 | } else { 50 | this.addToUpvoters(); 51 | if (this.votes.score == -1) { 52 | this.votes.score = 1; 53 | } else { 54 | this.votes.score++; 55 | } 56 | } 57 | 58 | this.removeFromDownvotterList(); 59 | }, 60 | downVote(model_name, model_id) { 61 | if (!this.$auth.loggedIn) { 62 | swal({ 63 | title: "আপনি লগইন অবস্থায় নেই", 64 | icon: "error", 65 | }); 66 | return; 67 | } 68 | 69 | this.$axios.$post(`api/vote`, { 70 | model_name, 71 | model_id, 72 | vote: "DOWN_VOTE", 73 | }); 74 | 75 | if (this.isDownvotted) { 76 | this.removeFromDownvotterList(); 77 | this.votes.score++; 78 | } else { 79 | this.addToDownvoters(); 80 | if (this.votes.score == 1) { 81 | this.votes.score = -1; 82 | } else { 83 | this.votes.score--; 84 | } 85 | } 86 | 87 | this.removeFromUpvotterList(); 88 | }, 89 | }, 90 | }; 91 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "techdiary-client", 3 | "version": "1.0.0", 4 | "private": true, 5 | "engines": { 6 | "node": ">=14.0.0 <16.0.0" 7 | }, 8 | "scripts": { 9 | "dev": "nuxt", 10 | "build": "nuxt build", 11 | "start": "nuxt start", 12 | "generate": "nuxt generate", 13 | "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", 14 | "lint": "npm run lint:js" 15 | }, 16 | "dependencies": { 17 | "@netsells/nuxt-hotjar": "^0.1.3", 18 | "@nuxt/content": "^1.15.1", 19 | "@nuxtjs/auth-next": "^5.0.0-1624817847.21691f1", 20 | "@nuxtjs/axios": "^5.13.6", 21 | "@nuxtjs/cloudinary": "^1.0.3", 22 | "@nuxtjs/dayjs": "^1.4.1", 23 | "@nuxtjs/sentry": "^7.0.3", 24 | "@nuxtjs/toast": "^3.3.1", 25 | "algoliasearch": "^4.12.1", 26 | "bnnum": "^1.0.6", 27 | "codemirror": "^5.62.3", 28 | "core-js": "^3.15.1", 29 | "dayjs": "^1.11.7", 30 | "highlight.js": "^11.7.0", 31 | "lodash.debounce": "^4.0.8", 32 | "mavon-editor": "^2.10.4", 33 | "nuxt": "^2.15.8", 34 | "nuxt-seo-meta": "^2.3.1", 35 | "sweetalert": "^2.1.2", 36 | "vue-input-autowidth": "^1.0.11", 37 | "vue-multiselect": "^2.1.6", 38 | "vue-observe-visibility": "^1.0.0", 39 | "vue-tour": "^2.0.0", 40 | "yup": "^0.32.9" 41 | }, 42 | "devDependencies": { 43 | "@nuxt/postcss8": "^1.1.3", 44 | "@nuxtjs/color-mode": "^2.1.1", 45 | "@nuxtjs/google-analytics": "^2.4.0", 46 | "@tailwindcss/aspect-ratio": "^0.4.0", 47 | "@tailwindcss/forms": "^0.5.3", 48 | "@tailwindcss/line-clamp": "^0.3.1", 49 | "@tailwindcss/typography": "^0.5.9", 50 | "autoprefixer": "^10.4.13", 51 | "fibers": "^5.0.3", 52 | "postcss": "^8.4.5", 53 | "prettier": "2.8.3", 54 | "sass": "^1.36.0", 55 | "sass-loader": "^13.2.0", 56 | "tailwindcss": "^3.2.4" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pages/_username/articles.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 76 | -------------------------------------------------------------------------------- /pages/auth/login.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 65 | -------------------------------------------------------------------------------- /pages/auth/oauth-callback.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 49 | -------------------------------------------------------------------------------- /pages/auth/register.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 100 | -------------------------------------------------------------------------------- /pages/contest/_slug.vue: -------------------------------------------------------------------------------- 1 | 67 | 68 | 81 | 82 | 92 | -------------------------------------------------------------------------------- /pages/contest/index.vue: -------------------------------------------------------------------------------- 1 | 87 | 88 | 99 | -------------------------------------------------------------------------------- /pages/dashboard/bookmarks.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 83 | -------------------------------------------------------------------------------- /pages/dashboard/diaries/edit/_id.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /pages/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /pages/dashboard/sessions.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /pages/dashboard/settings.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 69 | -------------------------------------------------------------------------------- /pages/pages/_slug.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 28 | -------------------------------------------------------------------------------- /pages/tags/_tag.vue: -------------------------------------------------------------------------------- 1 | 36 | 78 | 79 | 98 | -------------------------------------------------------------------------------- /pages/test.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /pages/thumbnail.vue: -------------------------------------------------------------------------------- 1 | 26 | 40 | -------------------------------------------------------------------------------- /plugins/clickaway.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | 3 | Vue.directive("click-away", { 4 | bind: function (el, binding, vnode) { 5 | el.clickOutsideEvent = function (event) { 6 | // here I check that click was outside the el and his children 7 | if (!(el == event.target || el.contains(event.target))) { 8 | // and if it did, call method provided in attribute value 9 | vnode.context[binding.expression](event); 10 | } 11 | }; 12 | document.body.addEventListener("click", el.clickOutsideEvent); 13 | }, 14 | unbind: function (el) { 15 | document.body.removeEventListener("click", el.clickOutsideEvent); 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /plugins/editor.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import mavonEditor from "mavon-editor"; 3 | import "mavon-editor/dist/css/index.css"; 4 | 5 | // use 6 | Vue.use(mavonEditor); 7 | -------------------------------------------------------------------------------- /plugins/multi-select.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Multiselect from "vue-multiselect"; 3 | import "vue-multiselect/dist/vue-multiselect.min.css"; 4 | 5 | Vue.component("multi-select", Multiselect); 6 | -------------------------------------------------------------------------------- /plugins/resizeable-input.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueInputAutowidth from "vue-input-autowidth"; 3 | Vue.use(VueInputAutowidth); 4 | -------------------------------------------------------------------------------- /plugins/toast.client.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Toast from "vue-toastification"; 3 | import "vue-toastification/dist/index.css"; 4 | 5 | Vue.use(Toast, { 6 | position: "top-right" 7 | }); -------------------------------------------------------------------------------- /plugins/tour.client.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueTour from "vue-tour"; 3 | Vue.use(VueTour); 4 | -------------------------------------------------------------------------------- /plugins/visibility-observer.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import { ObserveVisibility } from "vue-observe-visibility"; 3 | 4 | Vue.directive("observe-visibility", ObserveVisibility); 5 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /static/branding/full-logo-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/branding/full-logo-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/branding/icon-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/branding/icon-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/branding/text-logo-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/branding/text-logo-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/favicon.ico -------------------------------------------------------------------------------- /static/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/fonts/Boshonto.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/Boshonto.woff -------------------------------------------------------------------------------- /static/fonts/Boshonto.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/Boshonto.woff2 -------------------------------------------------------------------------------- /static/fonts/KohinoorBangla-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/KohinoorBangla-Bold.woff -------------------------------------------------------------------------------- /static/fonts/KohinoorBangla-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/KohinoorBangla-Light.woff -------------------------------------------------------------------------------- /static/fonts/KohinoorBangla-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/KohinoorBangla-Medium.woff -------------------------------------------------------------------------------- /static/fonts/KohinoorBangla-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/KohinoorBangla-Regular.woff -------------------------------------------------------------------------------- /static/fonts/KohinoorBangla-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/KohinoorBangla-Semibold.woff -------------------------------------------------------------------------------- /static/fonts/kohinoor-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor-webfont.woff -------------------------------------------------------------------------------- /static/fonts/kohinoor-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor-webfont.woff2 -------------------------------------------------------------------------------- /static/fonts/kohinoor_bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_bold-webfont.woff -------------------------------------------------------------------------------- /static/fonts/kohinoor_bold-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_bold-webfont.woff2 -------------------------------------------------------------------------------- /static/fonts/kohinoor_light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_light-webfont.woff -------------------------------------------------------------------------------- /static/fonts/kohinoor_light-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_light-webfont.woff2 -------------------------------------------------------------------------------- /static/fonts/kohinoor_medium-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_medium-webfont.woff -------------------------------------------------------------------------------- /static/fonts/kohinoor_medium-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/fonts/kohinoor_medium-webfont.woff2 -------------------------------------------------------------------------------- /static/fonts/stylesheet.css: -------------------------------------------------------------------------------- 1 | /*! Generated by Font Squirrel (https://www.fontsquirrel.com) on March 21, 2021 */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'Kohinoor Bangla'; 7 | src: url('kohinoor_bold-webfont.woff2') format('woff2'), 8 | url('kohinoor_bold-webfont.woff') format('woff'); 9 | font-weight: 700; 10 | font-style: normal; 11 | 12 | } 13 | 14 | 15 | 16 | 17 | @font-face { 18 | font-family: 'Kohinoor Bangla'; 19 | src: url('kohinoor_light-webfont.woff2') format('woff2'), 20 | url('kohinoor_light-webfont.woff') format('woff'); 21 | font-weight: 300; 22 | font-style: normal; 23 | 24 | } 25 | 26 | 27 | 28 | 29 | @font-face { 30 | font-family: 'Kohinoor Bangla'; 31 | src: url('kohinoor_medium-webfont.woff2') format('woff2'), 32 | url('kohinoor_medium-webfont.woff') format('woff'); 33 | font-weight: 500; 34 | font-style: normal; 35 | 36 | } 37 | 38 | 39 | 40 | 41 | @font-face { 42 | font-family: 'Kohinoor Bangla'; 43 | src: url('kohinoor-webfont.woff2') format('woff2'), 44 | url('kohinoor-webfont.woff') format('woff'); 45 | font-weight: 400; 46 | font-style: normal; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /static/icons/external-link-sm.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/images/fabulous-late-night-working.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/images/fabulous-late-night-working.png -------------------------------------------------------------------------------- /static/images/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/images/hero.png -------------------------------------------------------------------------------- /static/images/robots-drones-artificial-intelligence-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/images/robots-drones-artificial-intelligence-1.png -------------------------------------------------------------------------------- /static/images/sadface.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/images/sadface.gif -------------------------------------------------------------------------------- /static/reactions/CHEER.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/CHEER.png -------------------------------------------------------------------------------- /static/reactions/FLYHIGH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/FLYHIGH.png -------------------------------------------------------------------------------- /static/reactions/HEART.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/HEART.png -------------------------------------------------------------------------------- /static/reactions/LIKE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/LIKE.png -------------------------------------------------------------------------------- /static/reactions/MONEY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/MONEY.png -------------------------------------------------------------------------------- /static/reactions/PARTY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/PARTY.png -------------------------------------------------------------------------------- /static/reactions/TROPHY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/TROPHY.png -------------------------------------------------------------------------------- /static/reactions/UNICORN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/reactions/UNICORN.png -------------------------------------------------------------------------------- /static/techdiary-imac-mockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/static/techdiary-imac-mockup.png -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techdiary-dev/techdiary.dev-nuxt2----deprecated/81820f57a527a7e71f5747fb3b0d2ae7641e5805/store/index.js -------------------------------------------------------------------------------- /store/search.js: -------------------------------------------------------------------------------- 1 | import algoliasearch from "algoliasearch"; 2 | 3 | const client = algoliasearch( 4 | process.env.NUXT_ENV_ALGOLIA_APP_ID, 5 | process.env.NUXT_ENV_ALGOLIA_API_KEY 6 | ); 7 | 8 | export const state = () => ({ 9 | results: [], 10 | meta: {}, 11 | loading: false, 12 | }); 13 | 14 | export const mutations = { 15 | SET_SEARCH_RESULT(state, payload) { 16 | const { hits, ...meta } = payload; 17 | 18 | // state.results.push(...hits) 19 | state.results = hits; 20 | state.meta = meta; 21 | }, 22 | SET_LOADING(state, payload) { 23 | state.loading = payload; 24 | }, 25 | }; 26 | 27 | export const actions = { 28 | doSearch({ commit }, payload) { 29 | /* 30 | payload = { index: '', query: '' } 31 | */ 32 | let index = client.initIndex(payload.index); 33 | 34 | commit("SET_LOADING", true); 35 | 36 | if (!payload.query) { 37 | commit("SET_SEARCH_RESULT", []); 38 | return; 39 | } 40 | 41 | index 42 | .search(payload.query, { hitsPerPage: 5000 }) 43 | .then((searchResult) => { 44 | commit("SET_SEARCH_RESULT", searchResult); 45 | commit("SET_LOADING", false); 46 | }) 47 | .catch((e) => { 48 | // commit("alert/ERROR_ALERT", JSON.stringify(e)) 49 | console.log(JSON.stringify(e)); 50 | }); 51 | }, 52 | }; 53 | -------------------------------------------------------------------------------- /store/ui.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state() { 3 | return { 4 | showLeftSidebar: false 5 | }; 6 | }, 7 | mutations: { 8 | SET_SHOW_LEFTSIDEBAR(state, payload) { 9 | state.showLeftSidebar = payload; 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const plugin = require("tailwindcss/plugin"); 2 | const colors = require("tailwindcss/colors"); 3 | 4 | const isFirefoxPlugin = plugin(function ({ addVariant, e, postcss }) { 5 | addVariant("firefox", ({ container, separator }) => { 6 | const isFirefoxRule = postcss.atRule({ 7 | name: "-moz-document", 8 | params: "url-prefix()", 9 | }); 10 | isFirefoxRule.append(container.nodes); 11 | container.append(isFirefoxRule); 12 | isFirefoxRule.walkRules((rule) => { 13 | rule.selector = `.${e( 14 | `firefox${separator}${rule.selector.slice(1)}` 15 | )}`; 16 | }); 17 | }); 18 | }); 19 | 20 | module.exports = { 21 | mode: "jit", 22 | content: [ 23 | "./components/**/*.{js,vue,ts}", 24 | "./layouts/**/*.vue", 25 | "./pages/**/*.vue", 26 | "./plugins/**/*.{js,ts}", 27 | "./nuxt.config.{js,ts}", 28 | ], 29 | darkMode: "class", // or 'media' or 'class' 30 | theme: { 31 | extend: { 32 | colors: { 33 | primary: "#8A9CFE", 34 | secondary: "#FDF9F3", 35 | slate: colors.slate, 36 | }, 37 | fontFamily: { 38 | KohinoorBangla: ["KohinoorBangla", "Nunito", "Arial"], 39 | siliguri: ["Hind Siliguri", "Nunito", "Arial"], 40 | mono: ["Fira Code", "techdiary-bangla", "monospace"], 41 | boshonto: ["Boshonto", "Kohinoor Bangla"], 42 | }, 43 | zIndex: { 44 | "-1": "-1", 45 | }, 46 | }, 47 | }, 48 | variants: { 49 | extend: {}, 50 | }, 51 | plugins: [ 52 | require("@tailwindcss/typography"), 53 | require("@tailwindcss/forms"), 54 | require("@tailwindcss/aspect-ratio"), 55 | require("@tailwindcss/line-clamp"), 56 | isFirefoxPlugin, 57 | ], 58 | }; 59 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [ 3 | { 4 | "src": "nuxt.config.js", 5 | "use": "@nuxtjs/vercel-builder", 6 | "config": { 7 | "serverFiles": [ 8 | ".nuxt/content/**", 9 | "content/**" 10 | ] 11 | } 12 | } 13 | ] 14 | } --------------------------------------------------------------------------------