├── .eslintrc.json ├── .gitignore ├── README.md ├── app ├── [id] │ └── page.tsx ├── add │ ├── layout.tsx │ └── page.tsx ├── edit │ └── [id] │ │ └── page.tsx ├── favicon.ico ├── feed │ ├── [id] │ │ └── page.tsx │ ├── layout.tsx │ └── page.tsx ├── globals.css ├── layout.tsx ├── login │ ├── layout.tsx │ └── page.tsx ├── page.tsx └── register │ ├── layout.tsx │ └── page.tsx ├── components.json ├── components ├── custom │ └── home.tsx ├── elements │ ├── colorpiscker.tsx │ ├── moodPicker.tsx │ ├── sliceText.ts │ └── swiper.tsx ├── screens │ ├── details.tsx │ ├── edit.tsx │ ├── feed.tsx │ ├── myDiaries.tsx │ ├── secrets.tsx │ └── settings.tsx └── ui │ ├── DatePickerWithPresets.tsx │ ├── badge.tsx │ ├── breadcrumb.tsx │ ├── button.tsx │ ├── calendar.tsx │ ├── card.tsx │ ├── dropdown-menu.tsx │ ├── form.tsx │ ├── input.tsx │ ├── label.tsx │ ├── popover.tsx │ ├── select.tsx │ ├── sheet.tsx │ ├── switch.tsx │ ├── table.tsx │ ├── textarea.tsx │ ├── toast.tsx │ ├── toaster.tsx │ ├── toggle-group.tsx │ ├── toggle.tsx │ ├── tooltip.tsx │ └── use-toast.ts ├── context ├── add.ts ├── color.ts ├── date.ts ├── diaryDetail.ts ├── images.ts ├── loggedIn.ts ├── mood.ts ├── myDetails.ts ├── page.tsx └── screens.ts ├── lib └── utils.ts ├── middleware └── authService.ts ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── 111.jpg ├── 116-1166655_spiral-binding-png-spiral-binder-coil-png-transparent-removebg-preview-removebg-preview(1).png ├── 2222.jpg ├── 68937983395.png ├── avatar.png ├── bg.png ├── bgb.png ├── book.png ├── colored-paper-sculpture-background-spring-memo-notes-illustration-set-diary-notebook-paper-memo_632180-956-removebg-preview.png ├── eee-removebg-preview.png ├── et.avif ├── ff.png ├── filmbg.jpg ├── hhh-removebg-preview.png ├── next.svg ├── noPost.png ├── nopost (2).png ├── ok.avif ├── one.avif ├── scratch.jpg ├── spinner.svg ├── spring.png ├── springer.png ├── thunderstorm-lightning-clip-art-thunder-removebg-preview.png ├── tttj.jpg ├── user.jpg ├── uuu.png ├── uuuu.jpg ├── vercel.svg └── yyy.avif ├── tailwind.config.ts ├── tsconfig.json └── utils └── dummy.ts /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My Space 🌟 2 | 3 | ![My Space](https://i.ibb.co/RzXXzzM/myspace.png) 4 | 5 | Hey there, welcome to My Space! This is where you can share your thoughts, memories, and connect with others. Let's break down what makes My Space awesome in simple terms: 6 | 7 | ## What's My Space All About? 8 | 9 | My Space is like your digital diary, but cooler! Here's what you can do: 10 | 11 | ### Features 12 | - **Choose Your Look**: Make your posts look cool with different styles. 13 | - **Keep It Private or Share**: Decide if you want only you to see or everyone. 14 | - **Show How You Feel**: Use emojis to show your mood. 15 | - **Share Photos**: Put up your favorite pictures. 16 | - **Make Your Profile Shine**: Add stuff to make your profile special. 17 | - **Keep Track of Everything**: See all your posts easily. 18 | - **Join the Conversation**: Comment, like, and dislike posts. 19 | - **Coming Soon**: We've got more cool stuff on the way! 20 | 21 | ## The Techy Stuff 💻 22 | 23 | Here's what makes My Space work: 24 | 25 | ### Backend 26 | - **Hono.js**: Makes sure everything runs smoothly. 27 | - **MongoDB**: Where we keep all your stuff safe. 28 | - **JWT (JSON Web Tokens)**: Keeps your account safe. 29 | - **Zod**: Checks if everything you type is okay. 30 | 31 | ### Frontend 32 | - **Next.js**: Makes everything look good on your screen. 33 | - **Zustand**: Helps keep everything organized. 34 | - **shadcn**: Adds style to the site. 35 | - **Tailwind CSS**: Helps make things look nice. 36 | 37 | ## How to Get Involved 🚀 38 | 39 | Want to help make My Space even better? Here's how: 40 | 41 | 1. **Fork** the project. 42 | 2. Create a new branch: `git checkout -b feature/your-feature`. 43 | 3. Make your changes: `git commit -m 'Add some feature'`. 44 | 4. Share your changes: `git push origin feature/your-feature`. 45 | 5. Send us a **pull request**. 46 | 47 | ## Found a Bug or Have Ideas? 48 | 49 | Got a problem or a cool idea? Tell us about it! I am here to make My Space awesome together! 50 | 51 | Let's make My Space the best place to be online! 🚀✨ 52 | -------------------------------------------------------------------------------- /app/[id]/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Image from "next/image"; 4 | import Link from "next/link"; // Import Link from Next.js for navigation 5 | import spring from "../../public/ff.png"; 6 | import { Button } from "@/components/ui/button"; 7 | import { useEffect, useState } from "react"; 8 | import useScreen from "@/context/screens"; 9 | import Feed from "@/components/screens/feed"; 10 | import SettingPage from "@/components/screens/settings"; 11 | import Secrets from "@/components/screens/secrets"; 12 | import MyDiaries from "@/components/screens/myDiaries"; 13 | import { useRouter } from "next/navigation"; // Corrected import statement 14 | import ColorPicker from "@/components/elements/colorpiscker"; 15 | import useColor from "@/context/color"; 16 | import { DatePickerWithPresets } from "@/components/ui/DatePickerWithPresets"; 17 | import useDate from "@/context/date"; 18 | import MoodPicker from "@/components/elements/moodPicker"; 19 | import useMood from "@/context/mood"; 20 | import { Textarea } from "@/components/ui/textarea"; 21 | import { 22 | ArrowLeft, 23 | BookHeartIcon, 24 | Globe, 25 | Lock, 26 | NotebookPen, 27 | SendIcon, 28 | SendToBackIcon, 29 | SkipBackIcon, 30 | User, 31 | } from "lucide-react"; 32 | import axios from "axios"; 33 | import pin from "../../public/uuu.png"; 34 | import test from "../../public/uuuu.jpg"; 35 | import { Input } from "@/components/ui/input"; 36 | import Draggable from "react-draggable"; 37 | import TesterApp from "@/components/elements/swiper"; 38 | import useImage from "@/context/images"; 39 | import useLoginData from "@/context/loggedIn"; 40 | import { getAuthToken } from "@/middleware/authService"; 41 | import { headers } from "next/headers"; 42 | import useDiaryState from "@/context/diaryDetail"; 43 | 44 | const cloudName = "dsaitxphg"; 45 | const preset_key = "ccelrtz4"; 46 | 47 | interface Comment { 48 | _id: string; 49 | content: string; 50 | userId: { 51 | _id: string; 52 | name: string; 53 | profilePicture: string; 54 | username: string; 55 | password: string; 56 | diaries: string[]; 57 | theme: string; 58 | __v: 0; 59 | }; 60 | diaryId: string; 61 | __v: number; 62 | } 63 | 64 | export default function Details({ params }: { params: { id: string } }) { 65 | // Receive onSelect as a prop 66 | const { screen } = useScreen(); 67 | const router = useRouter(); 68 | const { dateGet, setDateGet } = useDate(); 69 | const { setColor, color } = useColor(); 70 | const { mood, setMood } = useMood(); 71 | const [text, setText] = useState("talk to your little diary ..."); 72 | const { images, setImages, resetImages } = useImage(); 73 | const [diaryStatus, setDiaryStatus] = useState(false); 74 | const { isLoggedIn, setIsLoggedIn } = useLoginData(); 75 | const { diary, setDiary, resetDiary } = useDiaryState(); 76 | const [comments, setComments] = useState([]); 77 | const [comment, setComment] = useState(""); 78 | 79 | const fetchDetail = async () => { 80 | try { 81 | const token = getAuthToken(); 82 | const response = await axios.get( 83 | `${process.env.NEXT_PUBLIC_MAIN_URL}/free/${params.id}` 84 | ); 85 | 86 | const commentResponse = await axios.get( 87 | `${process.env.NEXT_PUBLIC_MAIN_URL}/diary/comments/${params.id}`, 88 | { 89 | headers: { 90 | Authorization: token, 91 | }, 92 | } 93 | ); 94 | 95 | // console.log("this is comments :", commentResponse.data.comments); 96 | setComments(commentResponse.data.comments); 97 | setDiary(response.data); 98 | setImages(response.data.picture); 99 | } catch (error: any) {} 100 | }; 101 | 102 | const commentHandler = async () => { 103 | const token = getAuthToken(); 104 | 105 | const response = await axios.post( 106 | `${process.env.NEXT_PUBLIC_MAIN_URL}/diary/comment/${params.id}`, 107 | { 108 | content: comment, 109 | }, 110 | { 111 | headers: { 112 | Authorization: token, 113 | }, 114 | } 115 | ); 116 | 117 | fetchDetail(); 118 | console.log(response.data); 119 | }; 120 | 121 | useEffect(() => { 122 | fetchDetail(); 123 | }, []); 124 | 125 | return ( 126 |
131 |
132 | 141 |
142 | 143 |
148 | spring 155 |
156 |

157 | Date: {diary && diary.date} 158 |

159 | 160 |
161 |
164 | {diary && diary.mood} 165 |
166 |
167 |

168 | {diary && diary.content} 169 |

170 |
171 |
176 | 185 | 186 |
187 | 188 |
189 |
190 |
191 | 192 |
193 | 194 |
195 | 196 |
197 |
198 | 199 | 203 | 204 |
205 | 206 |
207 |
208 |
209 |
210 | { 212 | setComment(e.target.value); 213 | }} 214 | className=" text-white w-full" 215 | placeholder=" comments here .." 216 | /> 217 | 218 | 224 |
225 |
226 | 227 |
228 | 229 |
230 | {comments.map((each: Comment) => { 231 | return ( 232 |
238 | commenter 245 |

{each.content}

246 |
247 | ); 248 | })} 249 |
250 |
251 |
252 |
253 |
254 | ); 255 | } 256 | -------------------------------------------------------------------------------- /app/add/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "../globals.css"; 4 | 5 | const inter = Inter({ subsets: ["latin"] }); 6 | 7 | export const metadata: Metadata = { 8 | title: "Create Next App", 9 | description: "Generated by create next app", 10 | }; 11 | 12 | export default function RootLayout({ 13 | children, 14 | }: Readonly<{ 15 | children: React.ReactNode; 16 | }>) { 17 | return ( 18 | 19 | 20 | {children} 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /app/add/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Image from "next/image"; 4 | import Link from "next/link"; // Import Link from Next.js for navigation 5 | import spring from "../../public/ff.png"; 6 | import { Button } from "@/components/ui/button"; 7 | import { useEffect, useState } from "react"; 8 | import useScreen from "@/context/screens"; 9 | import Feed from "@/components/screens/feed"; 10 | import SettingPage from "@/components/screens/settings"; 11 | import Secrets from "@/components/screens/secrets"; 12 | import MyDiaries from "@/components/screens/myDiaries"; 13 | import { useRouter } from "next/navigation"; // Corrected import statement 14 | import ColorPicker from "@/components/elements/colorpiscker"; 15 | import useColor from "@/context/color"; 16 | import { DatePickerWithPresets } from "@/components/ui/DatePickerWithPresets"; 17 | import useDate from "@/context/date"; 18 | import MoodPicker from "@/components/elements/moodPicker"; 19 | import useMood from "@/context/mood"; 20 | import { Textarea } from "@/components/ui/textarea"; 21 | import { BookHeartIcon, Globe, Lock, NotebookPen } from "lucide-react"; 22 | import axios from "axios"; 23 | import pin from "../../public/uuu.png"; 24 | import test from "../../public/uuuu.jpg"; 25 | import { Input } from "@/components/ui/input"; 26 | import Draggable from "react-draggable"; 27 | import TesterApp from "@/components/elements/swiper"; 28 | import useImage from "@/context/images"; 29 | import useLoginData from "@/context/loggedIn"; 30 | import { getAuthToken } from "@/middleware/authService"; 31 | import { headers } from "next/headers"; 32 | import Cropper from "cropperjs"; 33 | import "cropperjs/dist/cropper.css"; 34 | import ReactCrop from "react-image-crop"; 35 | import "react-image-crop/dist/ReactCrop.css"; 36 | 37 | const cloudName = "dsaitxphg"; 38 | const preset_key = "ccelrtz4"; 39 | 40 | export default function Dashboard() { 41 | // Receive onSelect as a prop 42 | const { screen } = useScreen(); 43 | const router = useRouter(); 44 | const { dateGet, setDateGet } = useDate(); 45 | const { setColor, color } = useColor(); 46 | const { mood, setMood } = useMood(); 47 | const [text, setText] = useState("talk to your little diary ..."); 48 | const { images, setImages, resetImages } = useImage(); 49 | const [diaryStatus, setDiaryStatus] = useState(false); 50 | const { isLoggedIn, setIsLoggedIn } = useLoginData(); 51 | 52 | // const [isPublic, setIsPublic] = useState(false); 53 | 54 | const [profilePic, setProfilePic] = useState([]); // Specify string[] for profilePic state 55 | 56 | const cancelHandler = () => { 57 | resetImages(); 58 | router.push("/"); 59 | }; 60 | 61 | const handleSubmit = async () => { 62 | const token = getAuthToken(); 63 | try { 64 | const response = await axios.post( 65 | `${process.env.NEXT_PUBLIC_MAIN_URL}/diary`, 66 | { 67 | date: dateGet, 68 | theme: color, 69 | mood: mood, 70 | content: text, 71 | picture: images, 72 | isPublic: diaryStatus, 73 | }, 74 | { 75 | headers: { 76 | Authorization: token, 77 | }, 78 | } 79 | ); 80 | 81 | router.push("/"); 82 | } catch (error: any) { 83 | if (error.response) { 84 | console.error("Error response:", error.response.data); 85 | } else if (error.request) { 86 | console.error("Error request:", error.request); 87 | } else { 88 | console.error("Error message:", error.message); 89 | } 90 | } 91 | }; 92 | 93 | useEffect(() => { 94 | const fetchData = async () => { 95 | const token = getAuthToken(); 96 | try { 97 | if (token) { 98 | setIsLoggedIn(true); 99 | resetImages(); 100 | } else { 101 | setIsLoggedIn(false); 102 | router.push("/login"); 103 | } 104 | } catch (error) { 105 | console.error("Error fetching data:", error); 106 | } 107 | }; 108 | 109 | fetchData(); 110 | }, [isLoggedIn]); 111 | 112 | function handleFile1(event: any) { 113 | const files = event.target.files; 114 | if (files) { 115 | const formDataArray: FormData[] = []; 116 | 117 | for (let i = 0; i < files.length; i++) { 118 | const formData = new FormData(); 119 | formData.append("file", files[i]); 120 | formData.append("upload_preset", preset_key); 121 | formDataArray.push(formData); 122 | } 123 | 124 | Promise.all( 125 | formDataArray.map((formData) => 126 | axios.post( 127 | `https://api.cloudinary.com/v1_1/${cloudName}/image/upload`, 128 | formData 129 | ) 130 | ) 131 | ) 132 | .then((responses) => { 133 | const urls = responses.map((res) => res.data.secure_url); 134 | 135 | setImages([...urls]); 136 | }) 137 | .catch((err) => console.error(err)); 138 | } 139 | } 140 | 141 | const handleTextChange = (e: any) => { 142 | setText(e.target.value); 143 | }; 144 | 145 | const MainScreen = () => { 146 | switch (screen) { 147 | case "Feed": 148 | return ; 149 | case "Settings": 150 | return ; 151 | case "Secrets": 152 | return ; 153 | case "MyDiaries": 154 | return ; 155 | default: 156 | return ; 157 | } 158 | }; 159 | 160 | return ( 161 |
162 |
165 | spring 172 |
173 |

174 | Date: {dateGet} 175 |

176 |
177 |
180 | {mood} 181 |
182 |
183 |

184 | {text} 185 |

186 | 187 |
188 |
189 | 190 |
191 |
192 | 193 | {/*
*/} 194 |
195 | 196 |
197 |
198 | 199 |
200 |
201 |
202 | 203 |
204 |
205 | 206 | 209 | 210 |
211 | 212 |
213 |
214 | 215 | 216 | 217 |