Created
September 22, 2025 18:26
-
-
Save codewithsadee/e60ef18142d09b2f8ca5ae991452a3bb to your computer and use it in GitHub Desktop.
Bitblog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| node_modules |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "semi": true, | |
| "singleQuote": true, | |
| "jsxSingleQuote": true, | |
| "printWidth": 80, | |
| "tabWidth": 2, | |
| "useTabs": false, | |
| "bracketSpacing": true, | |
| "bracketSameLine": false, | |
| "singleAttributePerLine": true, | |
| "arrowParens": "always", | |
| "endOfLine": "lf", | |
| "overrides": [ | |
| { | |
| "files": "*.html", | |
| "options": { | |
| "bracketSameLine": true, | |
| "singleAttributePerLine": false | |
| } | |
| } | |
| ] | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @import 'tailwindcss'; | |
| @import 'tw-animate-css'; | |
| @custom-variant dark (&:is(.dark *)); | |
| :root { | |
| --background: hsl(48 33.3333% 97.0588%); | |
| --foreground: hsl(44 19.4805% 15.098%); | |
| --card: hsl(48 33.3333% 97.0588%); | |
| --card-foreground: hsl(60 1.9608% 10%); | |
| --popover: hsl(0 0% 100%); | |
| --popover-foreground: hsl(50.7692 19.403% 13.1373%); | |
| --primary: hsl(28 100% 50%); | |
| --primary-foreground: hsl(0 0% 100%); | |
| --secondary: hsl(46.1538 22.807% 88.8235%); | |
| --secondary-foreground: hsl(50.7692 8.4967% 30%); | |
| --muted: hsl(44 29.4118% 90%); | |
| --muted-foreground: hsl(45 2.1739% 36.0784%); | |
| --accent: hsl(46.1538 22.807% 88.8235%); | |
| --accent-foreground: hsl(50.7692 19.403% 13.1373%); | |
| --destructive: hsl(60 1.9608% 10%); | |
| --destructive-foreground: hsl(0 0% 100%); | |
| --border: hsl(50 7.5% 84.3137%); | |
| --input: hsl(50.7692 7.9755% 68.0392%); | |
| --ring: hsl(28 100% 50%); | |
| --chart-1: hsl(27.7457 76.8889% 44.1176%); | |
| --chart-2: hsl(251.4545 84.6154% 74.5098%); | |
| --chart-3: hsl(46.1538 28.2609% 81.9608%); | |
| --chart-4: hsl(256.5517 49.1525% 88.4314%); | |
| --chart-5: hsl(28.1879 81.4208% 35.8824%); | |
| --sidebar: hsl(51.4286 25.9259% 94.7059%); | |
| --sidebar-foreground: hsl(60 2.521% 23.3333%); | |
| --sidebar-primary: hsl(15.1111 55.5556% 52.3529%); | |
| --sidebar-primary-foreground: hsl(0 0% 98.4314%); | |
| --sidebar-accent: hsl(46.1538 22.807% 88.8235%); | |
| --sidebar-accent-foreground: hsl(0 0% 20.3922%); | |
| --sidebar-border: hsl(0 0% 92.1569%); | |
| --sidebar-ring: hsl(0 0% 70.9804%); | |
| --font-sans: Poppins, ui-sans-serif, sans-serif, system-ui; | |
| --font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; | |
| --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, | |
| 'Liberation Mono', 'Courier New', monospace; | |
| --radius: 0.5rem; | |
| --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05); | |
| --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05); | |
| --shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 1px 2px -1px hsl(0 0% 0% / 0.1); | |
| --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 2px 4px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 4px 6px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 8px 10px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25); | |
| --tracking-normal: 0.025em; | |
| --spacing: 0.25rem; | |
| } | |
| .dark { | |
| --background: hsl(60 2.7027% 14.5098%); | |
| --foreground: hsl(51.4286 25.9259% 94.7059%); | |
| --card: hsl(60 2.7027% 14.5098%); | |
| --card-foreground: hsl(48 33.3333% 97.0588%); | |
| --popover: hsl(60 2.1277% 18.4314%); | |
| --popover-foreground: hsl(60 5.4545% 89.2157%); | |
| --primary: hsl(24.5815 94.9791% 53.1373%); | |
| --primary-foreground: hsl(0 0% 100%); | |
| --secondary: hsl(48 33.3333% 97.0588%); | |
| --secondary-foreground: hsl(60 2.1277% 18.4314%); | |
| --muted: hsl(60 3.8462% 10.1961%); | |
| --muted-foreground: hsl(52 12.8205% 77.0588%); | |
| --accent: hsl(48 9.8039% 10%); | |
| --accent-foreground: hsl(51.4286 25.9259% 94.7059%); | |
| --destructive: hsl(0 84.2365% 60.1961%); | |
| --destructive-foreground: hsl(0 0% 100%); | |
| --border: hsl(60 5.0847% 23.1373%); | |
| --input: hsl(52.5 5.1282% 30.5882%); | |
| --ring: hsl(24.5815 94.9791% 53.1373%); | |
| --chart-1: hsl(24.8619 73.8776% 48.0392%); | |
| --chart-2: hsl(251.4545 84.6154% 74.5098%); | |
| --chart-3: hsl(48 9.8039% 10%); | |
| --chart-4: hsl(248.2759 25.2174% 22.549%); | |
| --chart-5: hsl(25.0685 75.2577% 38.0392%); | |
| --sidebar: hsl(30 3.3333% 11.7647%); | |
| --sidebar-foreground: hsl(46.1538 9.7744% 73.9216%); | |
| --sidebar-primary: hsl(0 0% 20.3922%); | |
| --sidebar-primary-foreground: hsl(0 0% 98.4314%); | |
| --sidebar-accent: hsl(60 1.9608% 10%); | |
| --sidebar-accent-foreground: hsl(46.1538 9.7744% 73.9216%); | |
| --sidebar-border: hsl(0 0% 92.1569%); | |
| --sidebar-ring: hsl(0 0% 70.9804%); | |
| --font-sans: Poppins, ui-sans-serif, sans-serif, system-ui; | |
| --font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; | |
| --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, | |
| 'Liberation Mono', 'Courier New', monospace; | |
| --radius: 0.5rem; | |
| --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05); | |
| --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05); | |
| --shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 1px 2px -1px hsl(0 0% 0% / 0.1); | |
| --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 2px 4px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 4px 6px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), | |
| 0 8px 10px -1px hsl(0 0% 0% / 0.1); | |
| --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25); | |
| } | |
| @theme inline { | |
| --color-background: var(--background); | |
| --color-foreground: var(--foreground); | |
| --color-card: var(--card); | |
| --color-card-foreground: var(--card-foreground); | |
| --color-popover: var(--popover); | |
| --color-popover-foreground: var(--popover-foreground); | |
| --color-primary: var(--primary); | |
| --color-primary-foreground: var(--primary-foreground); | |
| --color-secondary: var(--secondary); | |
| --color-secondary-foreground: var(--secondary-foreground); | |
| --color-muted: var(--muted); | |
| --color-muted-foreground: var(--muted-foreground); | |
| --color-accent: var(--accent); | |
| --color-accent-foreground: var(--accent-foreground); | |
| --color-destructive: var(--destructive); | |
| --color-destructive-foreground: var(--destructive-foreground); | |
| --color-border: var(--border); | |
| --color-input: var(--input); | |
| --color-ring: var(--ring); | |
| --color-chart-1: var(--chart-1); | |
| --color-chart-2: var(--chart-2); | |
| --color-chart-3: var(--chart-3); | |
| --color-chart-4: var(--chart-4); | |
| --color-chart-5: var(--chart-5); | |
| --color-sidebar: var(--sidebar); | |
| --color-sidebar-foreground: var(--sidebar-foreground); | |
| --color-sidebar-primary: var(--sidebar-primary); | |
| --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); | |
| --color-sidebar-accent: var(--sidebar-accent); | |
| --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); | |
| --color-sidebar-border: var(--sidebar-border); | |
| --color-sidebar-ring: var(--sidebar-ring); | |
| --font-sans: var(--font-sans); | |
| --font-mono: var(--font-mono); | |
| --font-serif: var(--font-serif); | |
| --radius-sm: calc(var(--radius) - 4px); | |
| --radius-md: calc(var(--radius) - 2px); | |
| --radius-lg: var(--radius); | |
| --radius-xl: calc(var(--radius) + 4px); | |
| --shadow-2xs: var(--shadow-2xs); | |
| --shadow-xs: var(--shadow-xs); | |
| --shadow-sm: var(--shadow-sm); | |
| --shadow: var(--shadow); | |
| --shadow-md: var(--shadow-md); | |
| --shadow-lg: var(--shadow-lg); | |
| --shadow-xl: var(--shadow-xl); | |
| --shadow-2xl: var(--shadow-2xl); | |
| --tracking-tighter: calc(var(--tracking-normal) - 0.05em); | |
| --tracking-tight: calc(var(--tracking-normal) - 0.025em); | |
| --tracking-normal: var(--tracking-normal); | |
| --tracking-wide: calc(var(--tracking-normal) + 0.025em); | |
| --tracking-wider: calc(var(--tracking-normal) + 0.05em); | |
| --tracking-widest: calc(var(--tracking-normal) + 0.1em); | |
| } | |
| body { | |
| letter-spacing: var(--tracking-normal); | |
| } | |
| @layer base { | |
| * { | |
| @apply border-border outline-ring/50; | |
| } | |
| body { | |
| @apply bg-background text-foreground; | |
| letter-spacing: var(--tracking-normal); | |
| } | |
| .tiptap { | |
| @apply grow | |
| outline-none; | |
| h1, | |
| h2, | |
| h3 { | |
| @apply font-semibold | |
| tracking-tight | |
| [&:not(:first-child)]:mt-6; | |
| } | |
| h1 { | |
| @apply pb-2 | |
| text-3xl | |
| first:mt-0; | |
| } | |
| h2 { | |
| @apply text-2xl; | |
| } | |
| h3 { | |
| @apply text-xl; | |
| } | |
| p { | |
| @apply leading-7 | |
| [&:not(:first-child)]:mt-6; | |
| } | |
| blockquote { | |
| @apply mt-6 | |
| border-l-2 | |
| pl-6; | |
| } | |
| hr { | |
| @apply my-6; | |
| } | |
| ul { | |
| @apply my-6 | |
| ml-6 | |
| list-disc | |
| [&>li]:mt-2; | |
| } | |
| ol { | |
| @apply my-6 | |
| ml-6 | |
| list-decimal | |
| [&>li]:mt-2; | |
| } | |
| code { | |
| @apply bg-muted | |
| relative | |
| rounded | |
| px-[0.3rem] | |
| py-[0.2rem] | |
| font-mono; | |
| } | |
| .is-editor-empty:first-child { | |
| @apply before:text-muted-foreground | |
| before:content-[attr(data-placeholder)] | |
| before:float-left | |
| before:h-0 | |
| before:pointer-events-none; | |
| } | |
| } | |
| } | |
| @layer utilities { | |
| .container { | |
| @apply mx-auto | |
| px-4 | |
| lg:px-6; | |
| } | |
| .section { | |
| @apply py-6 md:py-10; | |
| } | |
| .section-title { | |
| @apply text-xl font-semibold mb-4 md:text-2xl md:mb-6; | |
| } | |
| } | |
| @layer components { | |
| .nav-link.active { | |
| @apply bg-accent; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @copyright 2025 codewithsadee | |
| * @license Apache-2.0 | |
| */ | |
| export interface User { | |
| _id: string; | |
| username: string; | |
| email: string; | |
| role: 'admin' | 'user'; | |
| firstName?: string; | |
| lastName?: string; | |
| socialLinks?: { | |
| website?: string; | |
| facebook?: string; | |
| instagram?: string; | |
| linkedin?: string; | |
| x?: string; | |
| youtube?: string; | |
| }; | |
| createdAt: string; | |
| updatedAt: string; | |
| } | |
| export interface Blog { | |
| _id: string; | |
| title: string; | |
| slug: string; | |
| content: string; | |
| banner: { | |
| url: string; | |
| width: number; | |
| height: number; | |
| }; | |
| author: User; | |
| viewsCount: number; | |
| likesCount: number; | |
| commentsCount: number; | |
| status: 'draft' | 'published'; | |
| publishedAt: string; | |
| updatedAt: string; | |
| } | |
| export interface Comment { | |
| _id: string; | |
| content: string; | |
| likesCount: number; | |
| user: User | null; | |
| blog: Blog; | |
| replies: Comment[]; | |
| createdAt: string; | |
| updatedAt: string; | |
| } | |
| export type PaginatedResponse<T, K extends string> = { | |
| limit: number; | |
| offset: number; | |
| total: number; | |
| } & { | |
| [key in K]: T[]; | |
| }; | |
| export type FieldValidationError = { | |
| /** | |
| * Indicates that the error occurred because a field had an invalid value | |
| */ | |
| type: 'field'; | |
| /** | |
| * The location within the request where this field is | |
| */ | |
| location: Location; | |
| /** | |
| * The path to the field which has a validation error | |
| */ | |
| path: string; | |
| /** | |
| * The value of the field. It might be unset if the value is hidden. | |
| */ | |
| value?: string; | |
| /** | |
| * The error message | |
| */ | |
| msg: string; | |
| }; | |
| export type ErrorCode = | |
| | 'BadRequest' | |
| | 'ValidationError' | |
| | 'AuthenticationError' | |
| | 'AuthorizationError' | |
| | 'NotFound' | |
| | 'ServerError'; | |
| export type ValidationError = { | |
| code: ErrorCode; | |
| errors: Record<string, FieldValidationError>; | |
| }; | |
| export type ErrorResponse = { | |
| code: ErrorCode; | |
| message: string; | |
| }; | |
| export interface ActionResponse<T = unknown> { | |
| ok: boolean; | |
| err?: ValidationError | ErrorResponse; | |
| data?: T; | |
| } | |
| export interface AuthResponse { | |
| accessToken: string; | |
| user: Pick<User, 'username' | 'email' | 'role'>; | |
| } | |
| export interface BlogCreateResponse { | |
| blog: Blog; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment