Skip to content

Commit 6309a22

Browse files
committed
Initial setup: Nuxt 4 with Nuxt UI 4, Firebase, and PostgreSQL
Set up a Reddit-like platform with the following features: - Nuxt 4 framework with TypeScript - Nuxt UI 4 for component library - Firebase Authentication for user management - PostgreSQL with Drizzle ORM for data persistence - Firebase Hosting configuration for deployment - Core features: communities, posts, comments, voting system - API routes for CRUD operations - Responsive UI components and layouts Technologies: - Frontend: Nuxt 4, Vue 3, Nuxt UI 4, Tailwind CSS - Backend: Nitro server, Firebase Admin SDK - Database: PostgreSQL with Drizzle ORM - Auth: Firebase Authentication - Deployment: Firebase Hosting + Cloud Functions
1 parent 5d7e367 commit 6309a22

32 files changed

Lines changed: 16386 additions & 3 deletions

.env.example

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Firebase Client Config (Public)
2+
NUXT_PUBLIC_FIREBASE_API_KEY=your_api_key
3+
NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_auth_domain
4+
NUXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
5+
NUXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_storage_bucket
6+
NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id
7+
NUXT_PUBLIC_FIREBASE_APP_ID=your_app_id
8+
9+
# Firebase Admin (Server-side only)
10+
FIREBASE_PRIVATE_KEY=your_private_key
11+
FIREBASE_CLIENT_EMAIL=your_client_email
12+
13+
# Database
14+
DATABASE_URL=postgresql://user:password@host:port/database
15+
16+
# Session
17+
SESSION_SECRET=your_session_secret_at_least_32_chars

.firebaserc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"projects": {
3+
"default": "albaniandotdev"
4+
}
5+
}

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Nuxt dev/build outputs
2+
.output
3+
.data
4+
.nuxt
5+
.nitro
6+
.cache
7+
dist
8+
9+
# Node dependencies
10+
node_modules
11+
12+
# Logs
13+
logs
14+
*.log
15+
16+
# Misc
17+
.DS_Store
18+
.fleet
19+
.idea
20+
21+
# Local env files
22+
.env
23+
.env.*
24+
!.env.example
25+
26+
# Firebase
27+
.firebase
28+
firebase-debug.log
29+
firestore-debug.log
30+
ui-debug.log
31+
32+
# Service account
33+
service-account.json

README.md

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,159 @@
1-
albdev.al
2-
=========
1+
# AlbDev - Albanian Developer Community
32

4-
Official Web Site
3+
A Reddit-like platform for Albanian developers built with Nuxt 4, Nuxt UI 4, Firebase, and PostgreSQL.
4+
5+
## Features
6+
7+
- 🔥 **Nuxt 4** - Latest version with enhanced performance
8+
- 🎨 **Nuxt UI 4** - Beautiful, accessible components
9+
- 🔐 **Firebase Authentication** - Secure user authentication
10+
- 💾 **PostgreSQL** - Robust relational database with Drizzle ORM
11+
- 🚀 **Firebase Hosting** - Serverless deployment
12+
- 📱 **Responsive Design** - Works on all devices
13+
-**Real-time Features** - Live updates and interactions
14+
15+
## Reddit-like Features
16+
17+
- Create and join communities
18+
- Post text, links, and images
19+
- Upvote/downvote system
20+
- Nested comments
21+
- User profiles with karma
22+
- Community moderation
23+
- Feed sorting (hot, new, top)
24+
25+
## Setup
26+
27+
### Prerequisites
28+
29+
- Node.js 18+ and npm
30+
- Firebase project
31+
- PostgreSQL database (Cloud SQL or other)
32+
33+
### Environment Variables
34+
35+
Create a `.env` file with:
36+
37+
```env
38+
# Firebase Client Config
39+
NUXT_PUBLIC_FIREBASE_API_KEY=your_api_key
40+
NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_auth_domain
41+
NUXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
42+
NUXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_storage_bucket
43+
NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
44+
NUXT_PUBLIC_FIREBASE_APP_ID=your_app_id
45+
46+
# Firebase Admin (Server-side)
47+
FIREBASE_PRIVATE_KEY=your_private_key
48+
FIREBASE_CLIENT_EMAIL=your_client_email
49+
50+
# Database
51+
DATABASE_URL=postgresql://user:password@host:port/database
52+
53+
# Session
54+
SESSION_SECRET=your_session_secret_min_32_chars
55+
```
56+
57+
### Installation
58+
59+
```bash
60+
# Install dependencies
61+
npm install
62+
63+
# Generate database migrations
64+
npm run db:generate
65+
66+
# Run migrations
67+
npm run db:migrate
68+
69+
# Start development server
70+
npm run dev
71+
```
72+
73+
### Database Setup
74+
75+
The project uses Drizzle ORM with PostgreSQL. Run migrations to set up the schema:
76+
77+
```bash
78+
npm run db:push
79+
```
80+
81+
To view your database in Drizzle Studio:
82+
83+
```bash
84+
npm run db:studio
85+
```
86+
87+
## Deployment
88+
89+
### Firebase Deployment
90+
91+
```bash
92+
# Build for production
93+
npm run build
94+
95+
# Deploy to Firebase
96+
firebase deploy
97+
```
98+
99+
### Required Firebase Services
100+
101+
1. **Authentication** - Enable Email/Password provider
102+
2. **Cloud Functions** - For server-side rendering
103+
3. **Hosting** - For static assets
104+
4. **Storage** (optional) - For image uploads
105+
106+
### Cloud SQL Setup
107+
108+
1. Create a Cloud SQL PostgreSQL instance
109+
2. Create a database
110+
3. Add connection string to `.env`
111+
4. Run migrations
112+
113+
## Project Structure
114+
115+
```
116+
├── components/ # Vue components
117+
├── composables/ # Composable functions
118+
├── layouts/ # App layouts
119+
├── middleware/ # Route middleware
120+
├── pages/ # App pages/routes
121+
├── plugins/ # Nuxt plugins
122+
├── server/ # Server-side code
123+
│ ├── api/ # API endpoints
124+
│ ├── database/ # Database schema
125+
│ ├── middleware/ # Server middleware
126+
│ └── utils/ # Server utilities
127+
├── drizzle.config.ts # Drizzle ORM config
128+
├── nuxt.config.ts # Nuxt configuration
129+
└── firebase.json # Firebase config
130+
```
131+
132+
## Development
133+
134+
```bash
135+
# Run dev server
136+
npm run dev
137+
138+
# Type checking
139+
npm run typecheck
140+
141+
# Lint code
142+
npm run lint
143+
144+
# Generate types
145+
npm run postinstall
146+
```
147+
148+
## Tech Stack
149+
150+
- **Framework**: Nuxt 4
151+
- **UI Library**: Nuxt UI 4 (Tailwind CSS)
152+
- **Authentication**: Firebase Auth
153+
- **Database**: PostgreSQL with Drizzle ORM
154+
- **Hosting**: Firebase Hosting + Cloud Functions
155+
- **Language**: TypeScript
156+
157+
## License
158+
159+
MIT

app.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<div>
3+
<NuxtLayout>
4+
<NuxtPage />
5+
</NuxtLayout>
6+
</div>
7+
</template>
8+
9+
<script setup lang="ts">
10+
useSeoMeta({
11+
title: 'AlbDev',
12+
description: 'Albanian Developer Community',
13+
ogTitle: 'AlbDev',
14+
ogDescription: 'Albanian Developer Community - Share, discuss, and learn together',
15+
ogImage: '/og-image.png',
16+
twitterCard: 'summary_large_image'
17+
})
18+
</script>

components/AuthForm.vue

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<template>
2+
<UCard>
3+
<template #header>
4+
<h2 class="text-xl font-bold">
5+
{{ isSignUp ? 'Create Account' : 'Welcome Back' }}
6+
</h2>
7+
</template>
8+
9+
<form @submit.prevent="handleSubmit" class="space-y-4">
10+
<UFormGroup v-if="isSignUp" label="Username" required>
11+
<UInput
12+
v-model="formData.username"
13+
placeholder="Enter username"
14+
icon="i-heroicons-user"
15+
/>
16+
</UFormGroup>
17+
18+
<UFormGroup label="Email" required>
19+
<UInput
20+
v-model="formData.email"
21+
type="email"
22+
placeholder="Enter email"
23+
icon="i-heroicons-envelope"
24+
/>
25+
</UFormGroup>
26+
27+
<UFormGroup label="Password" required>
28+
<UInput
29+
v-model="formData.password"
30+
type="password"
31+
placeholder="Enter password"
32+
icon="i-heroicons-lock-closed"
33+
/>
34+
</UFormGroup>
35+
36+
<UButton
37+
type="submit"
38+
block
39+
size="lg"
40+
:loading="loading"
41+
:label="isSignUp ? 'Sign Up' : 'Log In'"
42+
/>
43+
44+
<p class="text-center text-sm text-gray-600 dark:text-gray-400">
45+
{{ isSignUp ? 'Already have an account?' : "Don't have an account?" }}
46+
<button
47+
type="button"
48+
class="text-primary font-semibold hover:underline"
49+
@click="isSignUp = !isSignUp"
50+
>
51+
{{ isSignUp ? 'Log In' : 'Sign Up' }}
52+
</button>
53+
</p>
54+
</form>
55+
</UCard>
56+
</template>
57+
58+
<script setup lang="ts">
59+
const emit = defineEmits(['close'])
60+
61+
const { signIn, signUp } = useAuth()
62+
const isSignUp = ref(false)
63+
const loading = ref(false)
64+
65+
const formData = reactive({
66+
email: '',
67+
password: '',
68+
username: ''
69+
})
70+
71+
const handleSubmit = async () => {
72+
loading.value = true
73+
74+
try {
75+
if (isSignUp.value) {
76+
await signUp(formData.email, formData.password, formData.username)
77+
} else {
78+
await signIn(formData.email, formData.password)
79+
}
80+
emit('close')
81+
} catch (error: any) {
82+
console.error('Auth error:', error)
83+
// Show error toast
84+
} finally {
85+
loading.value = false
86+
}
87+
}
88+
</script>

components/CommunityCard.vue

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<NuxtLink
3+
:to="`/r/${community.name}`"
4+
class="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
5+
>
6+
<UAvatar
7+
:src="community.icon"
8+
:alt="community.displayName"
9+
size="sm"
10+
/>
11+
<div class="flex-1 min-w-0">
12+
<p class="font-semibold truncate">r/{{ community.name }}</p>
13+
<p class="text-xs text-gray-600 dark:text-gray-400">
14+
{{ community.memberCount }} members
15+
</p>
16+
</div>
17+
</NuxtLink>
18+
</template>
19+
20+
<script setup lang="ts">
21+
defineProps<{
22+
community: any
23+
compact?: boolean
24+
}>()
25+
</script>

0 commit comments

Comments
 (0)