Skip to content
Snippets Groups Projects
Commit 9e97eb0f authored by Yusuf Akgül's avatar Yusuf Akgül :hatching_chick:
Browse files

merged from main

parents c19fbd06 ad3f412d
No related branches found
No related tags found
1 merge request!6Sort + Search UI
Pipeline #34419 passed
Showing
with 235 additions and 209 deletions
......@@ -10,4 +10,8 @@ IGDB_IMG_BASE_URL="https://images.igdb.com/igdb/image/upload"
# For Authentication
TWITCH_CLIENT_ID="imdb_client_id"
TWITCH_CLIENT_SECRET="imdb_auth_id"
\ No newline at end of file
TWITCH_CLIENT_SECRET="imdb_auth_id"
# For Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="clerk_publishable_key"
CLERK_SECRET_KEY="clerk_secret_key"
\ No newline at end of file
......@@ -42,5 +42,4 @@ yarn-error.log*
next-env.d.ts
# prisma
/prisma/migrations/*
dev.db*
\ No newline at end of file
......@@ -20,31 +20,40 @@ image: node:20
stages: # List of stages for jobs, and their order of execution
- build
- test
- deploy
# - deploy
build-job: # This job runs in the build stage, which runs first.
stage: build
script:
- npm i
#- npm run build # needs automatic api key binding/refresh
- echo "Building application..."
- npm install
- npm run build
- echo "Application successfully built."
unit-test-job: # This job runs in the test stage.
stage: test # It only starts when the job in the build stage completes successfully.
script:
- echo "Running unit tests... This will take about 10 seconds."
- sleep 10
- sleep 1
- echo "Code coverage is 90%"
lint-test-job: # This job also runs in the test stage.
stage: test # It can run at the same time as unit-test-job (in parallel).
script:
- echo "Linting code... This will take about 10 seconds."
- sleep 10
- sleep 1
- echo "No lint issues found."
deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
environment: production
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
#deploy-job: # This job runs in the deploy stage.
# stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
# environment: production
# only:
# - main
# script:
# - echo "Deploying application..."
# - npm install --foreground-scripts # without this= error
# - npm install --global vercel
# - vercel pull --yes --environment=production --token=$VERCEL_TOKEN
# - vercel build --prod --token=$VERCEL_TOKEN
# - vercel deploy --prebuilt --prod --token=$VERCEL_TOKEN
# - echo "Application successfully deployed."
# project_ss23
# project_ss23_gameunity
## Projektbeschreibung
Unsere Idee ist es eine Social Media Plattform zu erstellen. Auf dieser Webseite soll es möglich
......
import { SignIn } from "@clerk/nextjs";
export default function Login() {
return (
<div>
<h1>Login WIP</h1>
</div>
)
return <SignIn />;
}
\ No newline at end of file
import { SignUp } from "@clerk/nextjs";
export default function Signup() {
return (
<div>
<h1>Signup WIP</h1>
</div>
)
return <SignUp />;
}
\ No newline at end of file
import { getGame, getGames } from "@/lib/igdb";
import { IGame } from "@/types/types";
import { IGame } from "@/types/igdb-types";
import Image from "next/image";
// renders a single game detail page
......@@ -10,17 +10,8 @@ export default async function GameDetail({ params }: { params: { gameid: string
<div>
<h1>Game Detail</h1>
<h1>{data[0].name}</h1>
<Image src={data[0].cover.url} alt={data[0].name} width={264} height={374} priority={true} />
<Image src={data[0].cover.url} alt={data[0].name} width={264} height={374} priority={true} style={{ width: 'auto', height: 'auto' }} />
<p>{data[0].summary}</p>
</div>
)
}
// pre-renders static paths for all fetched games for faster page loads
export async function generateStaticParams() {
const games = await getGames()
return games.map((game) => ({
gameid: game.id.toString(),
}));
}
\ No newline at end of file
"use client"
import Dashboard from "@/components/Dashboard";
import Sort from "@/components/Sort";
import { Grid, Hidden } from "@mui/material";
export default function DashboardLayout({
children,
}: {
......@@ -11,21 +7,9 @@ export default function DashboardLayout({
}) {
return (
<section>
<Grid container spacing={2}>
<Grid item xs={2}>
<Dashboard />
</Grid>
<Grid item xs={10} md={8}>
{children}
</Grid>
<Hidden mdDown>
<Grid item xs={2}>
<Sort />
</Grid>
</Hidden>
</Grid>
<div>
{children}
</div>
</section>
);
}
\ No newline at end of file
"use client"
import Game from "@/components/Game";
import Search from "@/components/Search";
import { getBaseURL } from "@/lib/utils";
import { IGame } from "@/types/types";
import { Card, CardContent, Grid, Stack } from "@mui/material";
import { Fragment } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import { useInfiniteQuery } from "react-query";
import { InfiniteScrollGames } from "@/components/InfiniteScroll";
// renders a list of games infinitely (presumably)
export default function GamesPage() {
const {
data,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
status,
} = useInfiniteQuery(
'infiniteGames',
async ({ pageParam = 1 }) =>
await fetch(
`${getBaseURL()}/api/games/?page=${pageParam}`,
{ cache: 'force-cache', }
).then((result) => result.json() as Promise<IGame[]>),
{
getNextPageParam: (lastPage, pages) => {
return lastPage.length > 0 ? pages.length + 1 : undefined;
},
}
);
export default async function GamesPage() {
return (
<Stack spacing={2}>
<Search />
<Card>
<CardContent>
{status === 'success' && (
<InfiniteScroll
dataLength={data?.pages.length * 20}
next={fetchNextPage}
hasMore={hasNextPage ? true : false}
loader={<h4>Loading...</h4>}
endMessage={
<p style={{ textAlign: 'center' }}>
<b>Yay! You have seen it all</b>
</p>
}
>
<Grid container spacing={2} justifyContent="center">
{data?.pages.map((page, i) => (
<Fragment key={i}>
{page.map((game: IGame) => (
<Grid item xs={12} ss={6} sm={4} md={3} lg={2} key={game.id}>
<Game id={game.id} name={game.name} cover={game.cover} key={game.id} />
</Grid>
))}
</Fragment>
))}
</Grid>
</InfiniteScroll>
)}
</CardContent>
</Card>
</Stack>
<div className="py-5">
<InfiniteScrollGames />
</div>
)
}
\ No newline at end of file
import PostMessageForm from "@/components/PostMessageForm";
import { prisma } from "@/prisma/db";
export default async function ThreadsPage() {
export default async function HomePage() {
let messages = null
try {
messages = await prisma.message.findMany()
......@@ -11,7 +11,8 @@ export default async function ThreadsPage() {
return (
<div>
<h1>Threads WIP</h1>
<h1>Home WIP</h1>
<p>This will be where all messages show up.</p>
<p>Needs a reload after posting!!</p>
{messages ?
......
import { UserProfile } from "@clerk/nextjs";
import { dark } from '@clerk/themes';
export default function User({ params }: { params: { userid: string } }) {
return (
<div>
<>
<h1>User Profile Page WIP</h1>
<p>Unique UserName: {params.userid}</p>
</div>
<p>Unique Page Params: {params.userid}</p>
<UserProfile appearance={{ baseTheme: dark }} />
</>
)
}
\ No newline at end of file
export default function Friends() {
export default function Followers() {
return (
<div>
<h1>Friends Page WIP</h1>
<h1>Followers Page WIP</h1>
</div>
)
}
\ No newline at end of file
export default function BlogsPage() {
export default function Help() {
return (
<div>
<h1>Blog WIP</h1>
<h1>Help Page WIP</h1>
</div>
)
}
\ No newline at end of file
import DashboardNav from "@/components/nav"
import { SiteFooter } from "@/components/site-footer"
import { dashboardConfig } from "@/lib/config/dashboard"
interface DashboardLayoutProps {
children?: React.ReactNode
}
export default async function ContentLayout({
children,
}: DashboardLayoutProps) {
return (
<div className="flex min-h-screen flex-col space-y-6">
<div className="container grid flex-1 gap-12 md:grid-cols-[200px_1fr]">
<aside className="hidden w-[200px] flex-col md:flex">
<div className="sticky top-0">
<DashboardNav items={dashboardConfig.sidebarNav} />
</div>
</aside>
<main className="flex w-full flex-1 flex-col overflow-hidden">
{children}
</main>
</div>
<SiteFooter className="border-t" />
</div>
)
}
\ No newline at end of file
......@@ -3,6 +3,10 @@ import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
const p = req.nextUrl.searchParams;
const games = await getGames(p.get('page') ? parseInt(p.get('page') as string) : undefined);
return NextResponse.json(games);
try {
const games = await getGames(p.get('page') ? parseInt(p.get('page') as string) : undefined);
return NextResponse.json(games);
} catch (error) {
return NextResponse.json(error, { status: 500 });
}
}
\ No newline at end of file
File moved
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
.dark {
--background: 224 71% 4%;
--foreground: 213 31% 91%;
--muted: 223 47% 11%;
--muted-foreground: 215.4 16.3% 56.9%;
--popover: 224 71% 4%;
--popover-foreground: 215 20.2% 65.1%;
--card: 224 71% 4%;
--card-foreground: 213 31% 91%;
--border: 216 34% 17%;
--input: 216 34% 17%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 1.2%;
--secondary: 222.2 47.4% 11.2%;
--secondary-foreground: 210 40% 98%;
--accent: 216 34% 17%;
--accent-foreground: 210 40% 98%;
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--ring: 216 34% 17%;
--radius: 0.5rem;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
\ No newline at end of file
"use client"
import { Inter } from 'next/font/google'
import './globals.css'
import { Container, CssBaseline, ThemeProvider } from "@mui/material"
import { createContext, useState } from "react"
import { QueryClient, QueryClientProvider } from "react-query"
import Header from "../components/Header"
import { Theme } from "./theme"
import Providers from '@/components/react-query/provider'
import SiteLoad from '@/components/site-loading'
import { ThemeProvider } from '@/components/ui/theme-provider'
import { ClerkProvider } from '@clerk/nextjs'
import { Suspense } from 'react'
const inter = Inter({ subsets: ['latin'] })
// metadata for the website
export const metadata = {
title: 'GameUnity',
description: 'Soon',
title: 'Create Next App',
description: 'Generated by create next app',
}
// for dark mode global context
export const ColorModeContext = createContext({ toggleColorMode: () => { } });
// this is the root layout for all pages ({children})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
const [queryClient] = useState(() => new QueryClient());
const [theme, colorMode] = Theme();
return (
<html lang="en">
<QueryClientProvider client={queryClient}>
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<body>
<Container maxWidth={false}>
<Header />
<html lang="en" suppressHydrationWarning>
<head />
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<Suspense fallback={<SiteLoad />}>
<ClerkProvider>
<Providers>
{children}
</Container>
</body>
</ThemeProvider>
</ColorModeContext.Provider>
</QueryClientProvider>
</Providers>
</ClerkProvider>
</Suspense>
</ThemeProvider>
</body>
</html>
)
}
// custom super small breakpoint for responsive design
declare module '@mui/material/styles' {
interface BreakpointOverrides {
ss: true;
}
}
\ No newline at end of file
import Link from "next/link";
import { buttonVariants } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import Link from 'next/link'
// renders home page
export default function Home() {
return (
<main>
<div>
<h1>Welcome to GameUnity!</h1>
<p>This will be our Home Page and is still WIP</p>
<Link href="/games">Games List Progress</Link>
</div>
</main>
<>
<section className="space-y-6 pb-8 pt-6 md:pb-12 md:pt-10 lg:py-32">
<div className="container flex max-w-[64rem] flex-col items-center gap-4 text-center">
<h1 className="font-heading text-3xl sm:text-5xl md:text-6xl lg:text-7xl">
Welcome to GameUnity!
</h1>
<p className="max-w-[42rem] leading-normal text-muted-foreground sm:text-xl sm:leading-8">
This will be our Home Page and is still WIP
</p>
<div className="space-x-4">
<Link href="/login" className={cn(buttonVariants({ size: "lg" }))}>
Log In
</Link>
<Link href="/signup" className={cn(buttonVariants({ size: "lg" }))}>
Sign Up
</Link>
</div>
<div className="flex flex-col space-y-4">
<Link href="/games" className={cn(buttonVariants({ size: "lg" }))}>
Games List Progress
</Link>
<Link href="/home" className={cn(buttonVariants({ size: "lg" }))}>
Home List Progress
</Link>
</div>
</div>
</section>
</>
)
}
\ No newline at end of file
}
import { Theme, createTheme } from "@mui/material";
import { useMemo, useState } from "react";
// this is the main theme for the website
export function Theme(): [Theme, { toggleColorMode: () => void }] {
const [mode, setMode] = useState<'light' | 'dark'>('dark');
const colorMode = useMemo(
() => ({
toggleColorMode: () => {
setMode((prevMode) => (prevMode === 'dark' ? 'light' : 'dark'));
},
}),
[],
);
return [useMemo(() =>
createTheme({
palette: {
mode: mode,
},
breakpoints: {
values: {
xs: 0,
ss: 300,
sm: 600,
md: 900,
lg: 1200,
xl: 1536,
},
},
}),
[mode],
),
colorMode];
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment