Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
VITE_FIREBASE_API_KEY=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_FIREBASE_PROJECT_ID=startupsindia-mediaplatform
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_APP_ID=
VITE_FIREBASE_MEASUREMENT_ID=
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist/
.vscode/
.env
.env.*
!.env.example
.DS_Store
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"dart.analysisExcludedFolders": [
"reference_files"
],
"search.exclude": {
"reference_files": true
}
}
157 changes: 157 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Admin Panel Handoff

This folder contains reference files from the Flutter app for building a separate admin web project against the same Firebase project.

The admin panel should not import these Dart files directly unless it is also a Dart/Flutter project. For a React, Next.js, or other web admin project, use them as the source of truth for Firestore collection names, document fields, and expected app behavior.

## Firebase Project

- Project ID: `startupsindia-mediaplatform`
- Auth domain: `startupsindia-mediaplatform.firebaseapp.com`
- Storage bucket: `startupsindia-mediaplatform.firebasestorage.app`

Use the same Firebase project in the admin web app.

## Reference Files

- `reference_files/firestore_repository.dart`
- Shows current Firestore collection names and operations.
- Current collections: `users`, `articles`, `user_topics`, `users/{uid}/notifications`.
- Includes article create/read/search, like/bookmark toggles, user profile save, topic follow/unfollow, and Cloudinary image upload.

- `reference_files/news_article_model.dart`
- Source of truth for current `articles/{articleId}` document fields.

- `reference_files/user_model.dart`
- Source of truth for current `users/{uid}` document fields.

- `reference_files/app_notification.dart`
- Source of truth for `users/{uid}/notifications/{notificationId}` fields.

- `reference_files/home_mock_data.dart`
- Shows the home modules that should eventually become admin-managed collections: featured stories, events, courses, communities, leaderboard, and funding cards.

## Current Firestore Schemas

### `articles/{articleId}`

```ts
{
authorId: string,
category: string,
headline: string,
sourceName: string,
sourceId: string,
sourceLogoAsset: string,
thumbnailAsset: string,
timeAgo: string,
body: string,
likesCount: number,
commentsCount: number,
isSourceFollowing: boolean,
isBookmarked: boolean,
isLiked: boolean,
isTrending: boolean,
likedBy: string[],
bookmarkedBy: string[],
createdAt: Timestamp,
updatedAt: Timestamp
}
```

Admin panel should add moderation/status fields:

```ts
{
status: "draft" | "pending" | "published" | "rejected" | "archived",
publishedAt: Timestamp | null,
reviewedBy: string | null,
reviewedAt: Timestamp | null,
rejectionReason: string
}
```

### `users/{uid}`

```ts
{
uid: string,
username: string,
fullName: string,
email: string,
phone: string,
displayName: string,
bio: string,
avatarUrl: string,
websiteUrl: string,
followersCount: number,
followingCount: number,
newsCount: number,
role: string,
interests: string[],
onboardingCompleted: boolean,
fcmTokens: string[],
updatedAt: Timestamp
}
```

Admin panel should add admin/account fields:

```ts
{
accountStatus: "active" | "suspended" | "deleted",
adminRole: "user" | "author" | "moderator" | "admin",
isVerified: boolean,
createdAt: Timestamp,
lastLoginAt: Timestamp
}
```

### `user_topics/{uid}`

```ts
{
topics: string[],
updatedAt: Timestamp
}
```

### `users/{uid}/notifications/{notificationId}`

```ts
{
type: "news" | "follow" | "interaction",
title: string,
subtitle: string,
createdAt: Timestamp,
avatarLabel: string,
isRead: boolean,
payload: string | null
}
```

## Admin Modules To Build

1. Admin auth and access guard
2. Articles CMS
3. Article moderation queue
4. User management
5. Topics/categories management
6. Sources/authors management
7. Notification campaigns
8. Comments moderation
9. Home modules CMS:
- Featured stories
- Funding opportunities
- Events
- Courses
- Communities
- Startup leaderboard

## Security Notes

- Do not trust client-side checks for admin access.
- Prefer Firebase Auth custom claims like `admin: true`.
- Alternatively, use a locked `admin_users/{uid}` collection.
- Sending push notifications must happen through Firebase Admin SDK, Cloud Functions, or a server route. Do not send FCM from the browser client SDK.

26 changes: 26 additions & 0 deletions fix_services.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require('fs');
const path = require('path');

const servicesDir = path.join(__dirname, 'src', 'services');

const files = fs.readdirSync(servicesDir);

files.forEach(file => {
if (file.endsWith('.ts')) {
const filePath = path.join(servicesDir, file);
let content = fs.readFileSync(filePath, 'utf8');

// Replace { id: item.id, ...(item.data() as Article) }
// with { ...(item.data() as Article), id: item.id }
content = content.replace(/\{\s*id:\s*([^,]+),\s*\.\.\.([^}]+)\}/g, '{ ...$2, id: $1 }');

// Same for uid
content = content.replace(/\{\s*uid:\s*([^,]+),\s*\.\.\.([^}]+)\}/g, '{ ...$2, uid: $1 }');

// Same for slug
content = content.replace(/\{\s*slug:\s*([^,]+),\s*\.\.\.([^}]+)\}/g, '{ ...$2, slug: $1 }');

fs.writeFileSync(filePath, content);
}
});
console.log('Services fixed');
19 changes: 19 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Startups India Admin</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Newsreader:wght@400;500;600&display=swap"
rel="stylesheet"
/>
</head>
<body class="min-h-screen bg-background text-foreground">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading