-
Notifications
You must be signed in to change notification settings - Fork 16
Description
3-gerbera/
├─ frontend/
│ ├─ app/
│ │ ├─ layout.tsx
│ │ ├─ page.tsx
│ │ ├─ ask/page.tsx
│ │ └─ admin/page.tsx
│ ├─ lib/
│ │ ├─ firebase.ts
│ │ ├─ auth.ts
│ │ └─ i18n.ts
│ ├─ public/
│ │ └─ logo.png
│ ├─ styles/
│ │ └─ globals.css
│ └─ package.json
├─ backend/
│ ├─ server.js
│ ├─ models/
│ │ └─ Question.js
│ ├─ routes/
│ │ └─ questions.js
│ └─ package.json
├─ README.md
└─ .gitignore
export const SUPER_ADMINS = ["artyomchik50@gmail.com"];
export function getRole(email?: string){
if(!email) return "USER";
return SUPER_ADMINS.includes(email?.toLowerCase()!) ? "SUPER_ADMIN" : "USER";
}
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY!,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN!,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!,
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const googleProvider = new GoogleAuthProvider();
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
i18n.use(initReactI18next).init({
resources: {
uz:{translation:{title:"3 Gerbera",ask:"Savol berish"}},
en:{translation:{title:"3 Gerbera",ask:"Ask a question"}},
ru:{translation:{title:"3 Gerbera",ask:"Задать вопрос"}},
zh:{translation:{title:"3 Gerbera",ask:"提问"}},
},
lng:"uz", fallbackLng:"en", interpolation:{escapeValue:false}
});
export default i18n;
"use client";
import { useTranslation } from "react-i18next";
import "../lib/i18n";
export default function Home() {
const { t, i18n } = useTranslation();
return (
{t("title")}
<select onChange={e=>i18n.changeLanguage(e.target.value)}>
UZ
EN
RU
ZH
{t("ask")}
);
}
"use client";
import { useState } from "react";
import { auth } from "../../lib/firebase";
export default function Ask() {
const [text,setText]=useState("");
const [type,setType]=useState("public");
async function submit(){
const user = auth.currentUser;
await fetch(${process.env.NEXT_PUBLIC_API_URL}/questions,{
method:"POST",
headers:{"Content-Type":"application/json"},
body:JSON.stringify({
text, type,
email:user?.email,
})
});
setText("");
alert("Yuborildi");
}
return (
<textarea value={text} onChange={e=>setText(e.target.value)} />
<select value={type} onChange={e=>setType(e.target.value)}>
Ommaviy
Shaxsiy
Yuborish
);
}
"use client";
import { useEffect, useState } from "react";
import { auth } from "../../lib/firebase";
import { getRole } from "../../lib/auth";
export default function Admin(){
const [items,setItems]=useState<any[]>([]);
useEffect(()=>{
const email = auth.currentUser?.email || "";
if (getRole(email)!=="SUPER_ADMIN") return;
fetch(${process.env.NEXT_PUBLIC_API_URL}/questions)
.then(r=>r.json()).then(setItems);
},[]);
return (
Admin Panel
{items.map(q=>(
{q.type} — {q.text} ({q.email})
))}
);
}
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import questions from "./routes/questions.js";
const app = express();
app.use(cors());
app.use(express.json());
mongoose.connect(process.env.MONGO_URL);
app.use("/questions", questions);
app.listen(process.env.PORT || 4000, ()=>console.log("Backend ishlamoqda"));
import mongoose from "mongoose";
export default mongoose.model("Question", new mongoose.Schema({
text:String,
type:String,
email:String,
createdAt:{type:Date, default:Date.now}
}));
import express from "express";
import Question from "../models/Question.js";
const r = express.Router();
r.post("/", async (req,res)=>{
const q = await Question.create(req.body);
res.json(q);
});
r.get("/", async (req,res)=>{
const all = await Question.find().sort({createdAt:-1});
res.json(all);
});
export default r;
NEXT_PUBLIC_FIREBASE_API_KEY=apiKey
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=authDomain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=projectId
NEXT_PUBLIC_API_URL=https://3-gerbera-backend.vercel.app
MONGO_URL=mongodb+srv://USERNAME:PASSWORD@cluster0.mongodb.net/3gerbera?retryWrites=true&w=majority
PORT=4000
