Skip to content

Commit

Permalink
Added workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
hkirat committed Sep 16, 2024
2 parents e087f2c + ccf889b commit 3c99b48
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 7,955 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Continuous Deployment
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.prod
push: true
tags: 100xdevs/dailycode:${{ github.sha }}

- name: Clone staging-ops repo, update, and push
env:
PAT: ${{ secrets.PAT }}
run: |
git clone https://github.com/code100x/staging-ops.git
cd staging-ops
sed -i 's|image: 100xdevs/dailycode:.*|image: 100xdevs/dailycode:${{ github.sha }}|' staging/dailycode/deployment.yml
git config user.name "GitHub Actions Bot"
git config user.email "[email protected]"
git add staging/dailycode/deployment.yml
git commit -m "Update dailycode image to ${{ github.sha }}"
git push https://${PAT}@github.com/code100x/staging-ops.git main
41 changes: 41 additions & 0 deletions .github/workflows/cd_prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Continuous Deployment (Prod)
on:
push:
branches: [ production ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.prod
push: true
tags: 100xdevs/dailycode:${{ github.sha }}

- name: Clone staging-ops repo, update, and push
env:
PAT: ${{ secrets.PAT }}
run: |
git clone https://github.com/code100x/staging-ops.git
cd staging-ops
sed -i 's|image: 100xdevs/dailycode:.*|image: 100xdevs/dailycode:${{ github.sha }}|' prod/dailycode/deployment.yml
git config user.name "GitHub Actions Bot"
git config user.email "[email protected]"
git add prod/dailycode/deployment.yml
git commit -m "Update dailycode image to ${{ github.sha }}"
git push https://${PAT}@github.com/code100x/staging-ops.git main
2 changes: 1 addition & 1 deletion Dockerfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ WORKDIR /usr/src/app
COPY . .
RUN yarn install
RUN cd packages/db && DATABASE_URL=$DATABASE_URL npx prisma generate && cd ../..
RUN DATABASE_URL=$DATABASE_URL npm run build
RUN DATABASE_URL=$DATABASE_URL yarn build

EXPOSE 3000

Expand Down
6 changes: 3 additions & 3 deletions apps/web/app/admin/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export default async function AdminLayout({ children }: { children: ReactNode })

if (!session?.user?.admin) {
return (
<div className="w-full min-h-screen flex items-center justify-center gap-4 p-4">
<div className="flex min-h-screen w-full items-center justify-center gap-4 p-4">
<div className="flex flex-col items-center justify-center space-y-4 text-center">
<div className="flex flex-col items-center space-y-2">
<LockClosedIcon className="w-14 h-14" />
<LockClosedIcon className="h-14 w-14" />
<div className="space-y-2">
<h1 className="text-3xl font-bold">Access Denied</h1>
<p className="text-sm text-gray-500 md:text-base dark:text-gray-400">
Expand All @@ -22,7 +22,7 @@ export default async function AdminLayout({ children }: { children: ReactNode })
</div>
<div className="flex flex-col gap-2 min-[400px]:flex-row">
<Link
className="inline-flex h-10 items-center justify-center rounded-md border border-gray-200 bg-white px-8 text-sm font-medium shadow-sm transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:pointer-events-none disabled:opacity-50 dark:border-gray-800 dark:bg-gray-950 dark:hover:bg-gray-800 dark:hover:text-gray-50 dark:focus-visible:ring-gray-300"
className="inline-flex h-10 items-center justify-center rounded-md border border-gray-200 bg-white px-8 text-sm font-medium shadow-sm transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:pointer-events-none disabled:opacity-50 dark:border-gray-800 dark:bg-gray-950 dark:hover:bg-gray-800 dark:hover:text-gray-50 dark:focus-visible:ring-gray-300"
href="/"
>
Return to the homepage
Expand Down
51 changes: 44 additions & 7 deletions apps/web/components/ContentSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,59 @@ import { useEffect, useRef, useState, useDeferredValue } from "react";
import Link from "next/link";
import { Cross2Icon, MagnifyingGlassIcon } from "@radix-ui/react-icons";
import { Dialog, DialogClose, DialogContent, Input, Card, CardDescription, CardHeader, CardTitle } from "@repo/ui";
import { getSearchResults } from "../lib/search";
import Image from "next/image";
/* import { getSearchResults } from "../lib/search";
import Image from "next/image"; */
import Fuse from "fuse.js";
import { TrackPros } from "./Tracks";

export function ContentSearch() {
type Payload = {
problemId: string;
trackTitle: string;
problemTitle: string;
trackId: string;
image: string;
};

interface DataItem {
payload: Payload;
}

export function ContentSearch({ tracks }: { tracks: TrackPros[] }) {
const [dialogOpen, setDialogOpen] = useState(false);
const [input, setInput] = useState("");
const [searchTracks, setSearchTracks] = useState<any[]>([]);
const [selectedIndex, setSelectedIndex] = useState(-1);
const scrollableContainerRef = useRef<HTMLDivElement>(null);
const deferredInput = useDeferredValue(input);

const [allTracks, setAllTracks] = useState<DataItem[]>([]);
useEffect(() => {
const updatedTracks: DataItem[] = [];
tracks.map((t) => {
t.problems.map((p) => {
updatedTracks.push({
payload: {
problemId: p.id,
trackTitle: t.title,
problemTitle: p.title,
trackId: t.id,
image: t.image,
},
});
});
});
setAllTracks(updatedTracks);
}, []);
useEffect(() => {
const fuse = new Fuse(allTracks, {
keys: ["payload.problemTitle"],
});

async function fetchSearchResults() {
if (deferredInput.length > 0) {
const data = await getSearchResults(deferredInput);
setSearchTracks(data);
/* const data = await getSearchResults(deferredInput); */
const data = fuse.search(deferredInput);
const items = data.map((result) => result.item);
setSearchTracks(items);
} else {
setSearchTracks([]);
}
Expand Down Expand Up @@ -119,7 +156,7 @@ export function ContentSearch() {
>
<Card className="p-2 w-full mx-2">
<div className="flex my-2">
<Image
<img
alt={track.payload.problemTitle}
src={track.payload.image}
className="flex mx-2 w-1/6 rounded-xl"
Expand Down
5 changes: 3 additions & 2 deletions apps/web/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import React, { useEffect, useState } from "react";
import { ContentSearch } from "../components/ContentSearch";
import { motion } from "framer-motion";
import { Spotlight } from "@repo/ui";
import { TrackPros } from "./Tracks";

export default function Hero() {
export default function Hero({ tracks }: { tracks: TrackPros[] }) {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

const handleMouseMove = (event: MouseEvent) => {
Expand Down Expand Up @@ -165,7 +166,7 @@ export default function Hero() {
<p className="text-primary/80 max-w-lg text-center tracking-tight md:text-lg font-light">
A platform where you'll find the right content to help you improve your skills and grow your knowledge.
</p>
<ContentSearch />
<ContentSearch tracks={tracks} />
</motion.div>
<Spotlight className="-top-40 left-0 md:left-60 md:-top-20 -z-10" fill="blue" />
</div>
Expand Down
37 changes: 23 additions & 14 deletions apps/web/components/Tracks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from "@repo/ui";
import { motion } from "framer-motion";

interface TrackPros extends Track {
export interface TrackPros extends Track {
problems: Problem[];
categories: {
category: {
Expand All @@ -39,26 +39,31 @@ interface TracksWithCategoriesProps {
categories: { id: string; category: string }[];
}

enum CohortGroup {
One = 1,
Two = 2,
Three = 3,
}

export const Tracks = ({ tracks, categories }: TracksWithCategoriesProps) => {
const [selectedCategory, setSelectedCategory] = useRecoilState(category);
const [filteredTracks, setFilteredTracks] = useState<TrackPros[]>(tracks);
const [visibleTracks, setVisibleTracks] = useState<TrackPros[]>([]);
const [sortBy, setSortBy] = useState<string>("new");
const [cohort2, setCohort2] = useState<boolean>(false);
const [isSelectOpen, setIsSelectOpen] = useState<boolean>(false);
const [cohort3, setCohort3] = useState<boolean>(false);
const [currentPage, setCurrentPage] = useState<number>(1);
const tracksPerPage = 10;
const [loading, setLoading] = useState<boolean>(true);
const [selectedCohort, setSelectedCohort] = useState<number | null>(null);

const tracksPerPage = 10;
const isCohort2Selected = selectedCohort === CohortGroup.Two;
const isCohort3Selected = selectedCohort === CohortGroup.Three;

const filterTracks = () => {
setLoading(true);
let newFilteredTracks = tracks;
if (cohort3) {
newFilteredTracks = newFilteredTracks.filter((t) => t.cohort === 3);
}
if (cohort2) {
newFilteredTracks = newFilteredTracks.filter((t) => t.cohort === 2);
if (selectedCohort) {
newFilteredTracks = newFilteredTracks.filter((t) => t.cohort === selectedCohort);
}
if (selectedCategory && selectedCategory !== "All") {
newFilteredTracks = newFilteredTracks.filter((t) =>
Expand Down Expand Up @@ -86,9 +91,13 @@ export const Tracks = ({ tracks, categories }: TracksWithCategoriesProps) => {
setLoading(false);
};

const handleCohortSelection = (cohort: number) => {
setSelectedCohort((prevCohort) => (prevCohort === cohort ? null : cohort));
};

useEffect(() => {
filterTracks();
}, [selectedCategory, cohort2, cohort3, tracks]);
}, [selectedCategory, selectedCohort, tracks]);

useEffect(() => {
sortTracks(sortBy);
Expand Down Expand Up @@ -127,17 +136,17 @@ export const Tracks = ({ tracks, categories }: TracksWithCategoriesProps) => {
<Button
size={"lg"}
variant={"ghost"}
onClick={() => setCohort2(!cohort2)}
className={cohort2 ? "bg-blue-600 text-white" : ""}
onClick={() => handleCohortSelection(2)}
className={isCohort2Selected ? "bg-blue-600 text-white hover:bg-blue-600" : ""}
>
Cohort 2.0
</Button>
<Separator className="w-0.5 h-4 bg-primary/25" />
<Button
size={"lg"}
variant={"ghost"}
onClick={() => setCohort3(!cohort3)}
className={cohort3 ? "bg-blue-600 text-white" : ""}
onClick={() => handleCohortSelection(3)}
className={isCohort3Selected ? "bg-blue-600 text-white hover:bg-blue-600" : ""}
>
Cohort 3.0
</Button>
Expand Down
10 changes: 8 additions & 2 deletions apps/web/components/admin/EditTrackCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { useState } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Button, Input } from "@repo/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Button, Input, Label } from "@repo/ui";
import { Track, Categories } from "@prisma/client";
import { updateTrack } from "../utils";

Expand All @@ -19,11 +19,12 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
const [description, setDescription] = useState(Track.description);
const [image, setImage] = useState(Track.image);
const [hidden, setHidden] = useState(Track.hidden);
const [cohort, setCohort] = useState(Track.cohort);
const [selectedCategory, setSelectedCategory] = useState<string[]>(Track.categories.map((item) => item.category.id));

function handleEdit(id: string) {
if (isEditing) {
updateTrack(id, { id, title, description, image, hidden, selectedCategory });
updateTrack(id, { id, title, description, image, hidden, selectedCategory, cohort });
return setIsEditing(false);
}
setIsEditing(true);
Expand All @@ -43,6 +44,7 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
setImage(Track.image);
setHidden(Track.hidden);
setIsEditing(Track.hidden);
setCohort(Track.cohort);
}
return (
<Card key={Track.id}>
Expand Down Expand Up @@ -90,6 +92,10 @@ const EditTrackCard = ({ Track, categories }: { Track: TrackCardProps; categorie
<CardDescription>
<Input onChange={(e) => setImage(e.target.value)} value={image} />
</CardDescription>
<CardDescription>
<Label>Cohort</Label>
<Input placeholder="Cohort" onChange={(e) => setCohort(Number(e.target.value))} value={cohort} />
</CardDescription>
<CardDescription>
{categories.map((item, i) => (
<Button
Expand Down
6 changes: 6 additions & 0 deletions apps/web/components/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export async function updateTrack(
selectedCategory?: string[];
problems?: { problem: Prisma.ProblemCreateManyInput; sortingOrder: number }[];
hidden: boolean;
cohort?: number;
}
) {
try {
Expand All @@ -276,6 +277,7 @@ export async function updateTrack(
description: data.description,
image: data.image,
hidden: data.hidden,
cohort: data.cohort,
},
});
await db.trackCategory.deleteMany({
Expand All @@ -293,6 +295,10 @@ export async function updateTrack(
});
});
}

await cache.evict("getAllTracks", []);
await getAllTracks();

return track;
} catch (e) {
console.log(e);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
4 changes: 4 additions & 0 deletions apps/web/screens/Admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const Admin = async () => {
});
return (
<div className="pt-2">
<p className="mb-2 text-center text-sm text-gray-500 dark:text-gray-400">
Note: Changes will be reflected at the Client FE but here in Admin you'll have to refresh in order to see the
changes
</p>
<div className="flex justify-center">
<Tabs defaultValue="auto" className="w-full">
<div className="flex justify-center my-2">
Expand Down
2 changes: 1 addition & 1 deletion apps/web/screens/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export async function Landing() {
return (
<div className="flex flex-col">
<AppbarClient />
<Hero />
<Hero tracks={tracks} />
<Tracks tracks={tracks} categories={categories} />
<FooterCTA />
<Footer />
Expand Down
Loading

0 comments on commit 3c99b48

Please sign in to comment.