-
Notifications
You must be signed in to change notification settings - Fork 139
Add: added newsletter to opensox.in #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 7 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
f4467c3
add: added the newsletter listing page, and the newsletter page, markβ¦
deveshru2712 2b2d35e
add: added routing on the newsletter click
deveshru2712 9fcd49d
add: added the loading skeleton, and only pro user can access the newβ¦
deveshru2712 c88532d
fix: add loadingstate, and user sub to the dependecies array
deveshru2712 c9ec8cb
rename: update the name of some files
deveshru2712 b087167
fix: made newsletter pro user exclusive
deveshru2712 357d163
remove: removed unused package
deveshru2712 61228ce
Merge remote-tracking branch 'origin/main' into add/add-newsletter
deveshru2712 30f4fbd
fix: fix the error raised by coderrabitai
deveshru2712 4bb31b3
remove the aria code as it was cause too much issue
deveshru2712 103b124
fix: fixed type error in get all newsletter utils function
deveshru2712 bcf3303
fix: made some recommended changes by coderrabbitai
deveshru2712 2b8fd59
Merge branch 'add/add-newsletter' of https://github.com/deveshru2712/β¦
deveshru2712 147c661
fix: made some recommended changes in the filter function
deveshru2712 f0ac259
fix: minute fix changes let to const
deveshru2712 2fa2f36
fix: change data to time in .md files and renamed a file
deveshru2712 e76e435
Merge branch 'main' into add/add-newsletter
deveshru2712 d442b6e
Merge branch 'main' into add/add-newsletter
deveshru2712 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| id: "unique-newsletter-id" | ||
| title: "Your Newsletter Title Goes Here" | ||
| date: "2025-11-16" | ||
| summary: "A brief 1-2 sentence summary of what this newsletter is about. This will appear below the title." | ||
| keywords: ["keyword1", "keyword2", "keyword3"] | ||
| readTime: "5 min read" | ||
| slug: "test" | ||
| --- | ||
|
|
||
| ## Add the content here |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| --- | ||
| id: "from-farm-to-founder" | ||
| title: "From Farm Boy to Founder: A Journey of Grit and Code" | ||
| date: "2025-10-23" | ||
| summary: "How one developer went from being a hotel receptionist with no college degree to building a startup with 10,000 users and multiple investment offersβall through self-taught programming and relentless determination." | ||
| keywords: | ||
| [ | ||
| "entrepreneurship", | ||
| "self-taught developer", | ||
| "startup journey", | ||
| "open source", | ||
| "career transition", | ||
| ] | ||
| readTime: "4 min read" | ||
| slug: "from-farm-to-founder" | ||
| --- | ||
|
|
||
|  | ||
|
|
||
| ## The Beginning: Breaking Free | ||
|
|
||
| I was born and raised on a farm. Despite nailing my studies, I got rejected by the air force. My parents, like many Indian parents, pushed hard for a government jobβthe "safe" option. At 18, I made a choice that would change everything: I left home. | ||
|
|
||
| My first job? A receptionist at a hotel. Not glamorous. Not prestigious. But it was _mine_. | ||
|
|
||
| ## The Pivot: A Computer and a Dream | ||
|
|
||
| I bought a computer with my savings. Late nights after hotel shifts, I taught myself programming. No college degree. No connections. No safety net. Just documentation, tutorials, and an obsessive drive to learn. | ||
|
|
||
| Eventually, I quit the hotel job and started from absolute scratch in tech. | ||
|
|
||
| ## The Grind: Open Source and GSoC | ||
|
|
||
| I dove into open source. My first Google Summer of Code application? **Rejected.** | ||
|
|
||
| But I didn't stop. I worked harder, contributed more, made genuine friends in the community. The second time around, I didn't just get inβI excelled. Internships followed. Job offers came. I even became a **GSoC mentor** myself. | ||
|
|
||
| While still learning and growing, I started earning lakhs. I paid my brother's college fees. I covered my father's medical treatment. The farm boy who left home at 18 was now supporting his family. | ||
|
|
||
| ## The Leap: Building Something Real | ||
|
|
||
| Despite the stable job and good income, I couldn't shake the itch to build something of my own. I started a side project. It grew to **10,000 users**. Then came **2 investment offers**. | ||
|
|
||
| The numbers spoke for themselves: my side project revenue crossed my salary. I left the job. | ||
|
|
||
| Now I'm scaling [opensox.ai](http://opensox.ai), and the journey continues. | ||
|
|
||
| ## The Lesson: You Can Just Do Things | ||
|
|
||
| There's no secret formula. No hidden shortcut. No "right" background. | ||
|
|
||
| What worked for me: | ||
|
|
||
| - **Self-belief over credentials** β No college degree couldn't stop me from learning to code | ||
| - **Community over isolation** β Open source connected me with people who became mentors and friends | ||
| - **Action over permission** β I didn't wait for someone to give me a chance; I created my own | ||
| - **Persistence over perfection** β Failed GSoC? Applied again. Got rejected? Kept building. | ||
|
|
||
| If you're reading this from a small town, from a non-tech background, from a place where startup dreams seem impossibleβknow this: **You can just do things.** | ||
|
|
||
| You don't need permission. You don't need a fancy degree. You need a computer, internet, and the refusal to quit. | ||
|
|
||
| _Want to follow my journey? Check out what we're building at [opensox.ai](http://opensox.ai)_ |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| --- | ||
| id: "ugly-execution" | ||
| title: "Ugly Execution: Why Imperfect Action Beats Perfect Planning" | ||
| date: "2025-11-16" | ||
| summary: "Stop waiting for perfect conditions. Learn why taking messy, imperfect action is infinitely more valuable than endless planning and preparation." | ||
| keywords: | ||
| [ | ||
| "productivity", | ||
| "mindset", | ||
| "execution", | ||
| "perfectionism", | ||
| "taking action", | ||
| "startup advice", | ||
| ] | ||
| readTime: "3 min read" | ||
| slug: "ugly-execution" | ||
| --- | ||
|
|
||
|  | ||
|
|
||
| I use the term **"ugly execution"** to define a state when you don't care about the perfectness in anything and just act. | ||
|
|
||
| When you understand that **life rewards action, not perfection.** | ||
|
|
||
| ## What Ugly Execution Looks Like | ||
|
|
||
| When your camera sucks, but still you hit that red button, record a scrappy and embarrassing video, and click on "post" and actually post it on YouTube. | ||
|
|
||
| When your website's UI sucks, authentication fails, gets "build errors" randomly, and lags like government websites, but you still publish it and let people use it. | ||
|
|
||
| When your resume looks like a blank slate, but you still apply for the job you wanted. | ||
|
|
||
| ## The Uncomfortable Truth | ||
|
|
||
| Your inner self is uncomfortable doing that, but you know that this **"chase of perfection" has the potential to kill your dreams.** | ||
|
|
||
| You know that if you don't act now, your net output in the future will be zero. | ||
|
|
||
| You know, acting, getting stuck, failing, making a stupid mistake, getting embarrassed, is **way better** than creating a mental prison for yourself by useless thinking, worrying, and planning. | ||
|
|
||
| ## Stop Chasing Aesthetics | ||
|
|
||
| Don't wait for the perfect: | ||
|
|
||
| - Time | ||
| - Camera | ||
| - Mic | ||
| - Laptop | ||
| - Place | ||
| - Circumstances | ||
| - Website | ||
| - People | ||
|
|
||
| You get the point. | ||
|
|
||
| ## The Only Rule That Matters | ||
|
|
||
| **JUST START WITH WHATEVER YOU HAVE** | ||
|
|
||
| **LET THE EXECUTION BE UGLY** | ||
|
|
||
| **JUST BE GOOD AT UGLY EXECUTION** | ||
|
|
||
| **LIFE WILL REWARD YOU EXPONENTIALLY.** | ||
|
|
||
| --- | ||
|
|
||
| _The difference between successful people and dreamers? Successful people ship ugly v1s. Dreamers wait for perfect v10s that never come._ |
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
124 changes: 124 additions & 0 deletions
124
apps/web/src/app/(main)/dashboard/newsletters/NewsletterPage.tsx
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| "use client"; | ||
|
|
||
| import { Search } from "lucide-react"; | ||
| import NewsletterItem from "@/components/newsletter/NewsletterItem"; | ||
| import CustomDropdown from "@/components/newsletter/Dropdown"; | ||
| import { useNewsletterFilters } from "@/hooks/useNewsletterFilters"; | ||
|
|
||
| interface NewsletterData { | ||
| id: string; | ||
| title: string; | ||
| summary: string; | ||
| keywords: string[]; | ||
| time: string; | ||
| readTime: string; | ||
| slug: string; | ||
| } | ||
|
|
||
| export default function NewsletterPage({ | ||
| initialData, | ||
| }: { | ||
| initialData: NewsletterData[]; | ||
| }) { | ||
| const { | ||
| search, | ||
| setSearch, | ||
| sortOrder, | ||
| setSortOrder, | ||
| selectedMonth, | ||
| setSelectedMonth, | ||
| monthOptions, | ||
| filteredAndSorted, | ||
| clearFilters, | ||
| hasActiveFilters, | ||
| resultCount, | ||
| } = useNewsletterFilters(initialData); | ||
|
|
||
| return ( | ||
| <div className="w-full py-6 px-4 sm:px-8"> | ||
| <div className="w-full"> | ||
| <h1 className="text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight"> | ||
| Newsletter | ||
| </h1> | ||
| <p className="mt-1 text-sm sm:text-base text-gray-300"> | ||
| Stay updated with our latest insights and stories | ||
| </p> | ||
| </div> | ||
|
|
||
| <div className="mt-8 w-full flex flex-col gap-4 sm:flex-row sm:flex-wrap sm:items-center"> | ||
| <div className="relative w-full flex-1"> | ||
| <Search | ||
| size={16} | ||
| className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" | ||
| /> | ||
| <input | ||
| type="text" | ||
| placeholder="Search newsletter..." | ||
| value={search} | ||
| onChange={(e) => setSearch(e.target.value)} | ||
| className=" | ||
| w-full bg-white/5 border border-white/10 rounded-lg | ||
| px-9 py-2 text-sm text-gray-200 placeholder-gray-400 | ||
| focus:outline-none focus:border-purple-400 | ||
| transition-all duration-200 | ||
| " | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="flex flex-row w-full sm:w-auto gap-3"> | ||
| <div className="w-full sm:w-40"> | ||
| <CustomDropdown | ||
| value={selectedMonth} | ||
| onChange={setSelectedMonth} | ||
| options={monthOptions} | ||
| /> | ||
| </div> | ||
| <div className="w-full sm:w-32"> | ||
| <CustomDropdown | ||
| value={sortOrder} | ||
| onChange={setSortOrder} | ||
| options={[ | ||
| { label: "Newest First", value: "newest" }, | ||
| { label: "Oldest First", value: "oldest" }, | ||
| ]} | ||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| {hasActiveFilters && ( | ||
| <div className="text-sm text-gray-400 mt-2"> | ||
| {resultCount} result{resultCount !== 1 ? "s" : ""} found | ||
| </div> | ||
| )} | ||
|
|
||
| <div className="mt-12 flex flex-col gap-5"> | ||
| {filteredAndSorted.length > 0 ? ( | ||
| filteredAndSorted.map((item) => ( | ||
| <NewsletterItem | ||
| key={item.id} | ||
| title={item.title} | ||
| summary={item.summary} | ||
| time={item.time} | ||
| keywords={item.keywords} | ||
| readTime={item.readTime} | ||
| slug={item.slug} | ||
| /> | ||
| )) | ||
| ) : ( | ||
| <div className="text-center py-12"> | ||
| <p className="text-gray-400 text-lg">No newsletters found.</p> | ||
| {hasActiveFilters && ( | ||
| <button | ||
| onClick={clearFilters} | ||
| className="mt-4 text-purple-400 hover:text-purple-300 text-sm underline" | ||
| > | ||
| Clear all filters | ||
| </button> | ||
| )} | ||
| </div> | ||
| )} | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
31 changes: 31 additions & 0 deletions
31
apps/web/src/app/(main)/dashboard/newsletters/[slug]/layout.tsx
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| "use client"; | ||
|
|
||
| import { useEffect } from "react"; | ||
| import { useRouter } from "next/navigation"; | ||
| import NewsletterSkeleton from "@/components/newsletter/NewsletterSkeleton"; | ||
| import { useSubscription } from "@/hooks/useSubscription"; | ||
|
|
||
| export default function NewsletterLayout({ | ||
| children, | ||
| }: { | ||
| children: React.ReactNode; | ||
| }) { | ||
| const router = useRouter(); | ||
| const { isLoading, isPaidUser } = useSubscription(); | ||
|
|
||
| useEffect(() => { | ||
| if (!isLoading && !isPaidUser) { | ||
| router.replace("/pricing"); | ||
| } | ||
| }, [isLoading, isPaidUser, router]); | ||
|
|
||
| if (isLoading) { | ||
| return <NewsletterSkeleton />; | ||
| } | ||
|
|
||
| if (!isPaidUser) { | ||
| return null; | ||
| } | ||
|
|
||
| return <>{children}</>; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.