Redid the front end so it now uses gitea as data source
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
parent
18c1970550
commit
6fa3241768
@ -1 +1,2 @@
|
|||||||
NEXT_PUBLIC_GITHUB_USERNAME=Guusvanmeerveld
|
NEXT_PUBLIC_GITEA_USERNAME=Guusvanmeerveld
|
||||||
|
NEXT_PUBLIC_GITEA_SERVER=git.guusvanmeerveld.dev
|
||||||
|
@ -1,67 +1,3 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"extends": "next/core-web-vitals"
|
||||||
"env": {
|
}
|
||||||
"node": true,
|
|
||||||
"es6": true
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 8
|
|
||||||
},
|
|
||||||
"plugins": [
|
|
||||||
"prettier",
|
|
||||||
"css-modules"
|
|
||||||
],
|
|
||||||
"ignorePatterns": [
|
|
||||||
"node_modules/*",
|
|
||||||
".next/*",
|
|
||||||
".out/*"
|
|
||||||
],
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:css-modules/recommended"
|
|
||||||
],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": [
|
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx"
|
|
||||||
],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"settings": {
|
|
||||||
"react": {
|
|
||||||
"version": "detect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"node": true,
|
|
||||||
"es6": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"plugin:react/recommended",
|
|
||||||
"plugin:react-hooks/recommended",
|
|
||||||
"plugin:jsx-a11y/recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"prettier/prettier": "error",
|
|
||||||
"react/prop-types": "off",
|
|
||||||
"react/react-in-jsx-scope": "off",
|
|
||||||
"jsx-a11y/anchor-is-valid": "off",
|
|
||||||
"jsx-a11y/no-autofocus": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error"
|
|
||||||
],
|
|
||||||
"@typescript-eslint/explicit-function-return-type": [
|
|
||||||
"warn",
|
|
||||||
{
|
|
||||||
"allowExpressions": true,
|
|
||||||
"allowConciseArrowFunctionExpressionsStartingWithVoid": true,
|
|
||||||
"allowTypedFunctionExpressions": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"stylelint-config-standard",
|
|
||||||
"stylelint-config-idiomatic-order"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"indentation": "tab"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,10 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
/**
|
/**
|
||||||
* @type {import('next/dist/next-server/server/config').NextConfig}
|
* @type {import('next').NextConfig}
|
||||||
**/
|
**/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
}
|
images: {
|
||||||
|
domains: [process.env.NEXT_PUBLIC_GITEA_SERVER]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -1,40 +1,47 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
|
import z from "zod";
|
||||||
|
|
||||||
import { BestRepository } from "@interfaces/repository";
|
import { RepositoryResponse } from "@models/responses";
|
||||||
|
|
||||||
const BestRepository: FC<{ repository: BestRepository }> = ({ repository }) => {
|
const BestRepository: FC<{ repository: z.infer<typeof RepositoryResponse> }> =
|
||||||
return (
|
({ repository }) => {
|
||||||
<div className="hero bg-primary">
|
return (
|
||||||
<div className="container">
|
<div className="hero bg-primary">
|
||||||
<div className="columns">
|
<div className="container">
|
||||||
<div className="column col-8 col-md-12 col-mx-auto">
|
<div className="columns">
|
||||||
<h3 className="text-secondary">My most popular project:</h3>
|
<div className="column col-8 col-md-12 col-mx-auto">
|
||||||
<h1>{repository.name}</h1>
|
<h3 className="text-secondary">My most popular project:</h3>
|
||||||
<h3 className="text-secondary">
|
<h1>{repository.full_name}</h1>
|
||||||
{repository.stargazers_count} Star(s)
|
<h3 className="text-secondary">{repository.size} byes</h3>
|
||||||
</h3>
|
<h5>{repository.description}</h5>
|
||||||
<h5>{repository.description}</h5>
|
<p className="text-secondary">
|
||||||
<p className="text-secondary">
|
Written in {repository.language}, has{" "}
|
||||||
Written in {repository.language}, has{" "}
|
{repository.open_issues_count} issue(s) and{" "}
|
||||||
{repository.open_issues_count} issue(s) and{" "}
|
{repository.forks_count} fork(s).
|
||||||
{repository.forks_count} fork(s).
|
</p>
|
||||||
</p>
|
|
||||||
|
|
||||||
<Link href={repository.url}>
|
<p>
|
||||||
<a className="btn mr-2">Github</a>
|
<Link href={repository.html_url}>
|
||||||
</Link>
|
<a className="btn mr-2">Github</a>
|
||||||
{repository.homepage && (
|
</Link>
|
||||||
<Link href={repository.homepage}>
|
{repository.website && (
|
||||||
<a className="btn">Website</a>
|
<Link href={repository.website}>
|
||||||
</Link>
|
<a className="btn">Website</a>
|
||||||
)}
|
</Link>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h5 className="text-secondary">
|
||||||
|
Last commit on{" "}
|
||||||
|
{new Date(repository.updated_at).toLocaleDateString()}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
export default BestRepository;
|
export default BestRepository;
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
import { FC } from "react";
|
|
||||||
|
|
||||||
import styles from "./intro.module.scss";
|
|
||||||
|
|
||||||
const Intro: FC<{ isAvailable: boolean }> = ({ isAvailable }) => {
|
|
||||||
return (
|
|
||||||
<div className={styles.main}>
|
|
||||||
<div className="container">
|
|
||||||
<div className="columns">
|
|
||||||
<div className="column col-8 col-md-12 col-mx-auto text-center">
|
|
||||||
<h1>Guus van Meerveld</h1>
|
|
||||||
|
|
||||||
<h3>
|
|
||||||
Open source <u>web developer</u>
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
href={`https://github.com/${process.env.NEXT_PUBLIC_GITHUB_USERNAME}`}
|
|
||||||
className="btn btn-primary mr-2"
|
|
||||||
>
|
|
||||||
Github
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="mailto:contact@guusvanmeerveld.dev"
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Contact
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p className="text-gray">
|
|
||||||
Availibility: {isAvailable && "Available"}
|
|
||||||
{!isAvailable && "Not available"}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Intro;
|
|
@ -0,0 +1,67 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import z from "zod";
|
||||||
|
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
import { UserResponse } from "@models/responses";
|
||||||
|
import { giteaServerUrl } from "@utils/config";
|
||||||
|
import multipleClassNames from "@utils/multipleClassNames";
|
||||||
|
|
||||||
|
import styles from "./user.module.scss";
|
||||||
|
|
||||||
|
const User: FC<{ isAvailable: boolean; user: z.infer<typeof UserResponse> }> =
|
||||||
|
({ isAvailable, user }) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.main}>
|
||||||
|
<div className="container">
|
||||||
|
<div className="columns">
|
||||||
|
<div
|
||||||
|
className={multipleClassNames(
|
||||||
|
"column",
|
||||||
|
"col-4",
|
||||||
|
"col-mx-auto",
|
||||||
|
styles.avatarCol
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className={styles.avatarContainer}>
|
||||||
|
<Image
|
||||||
|
src={user.avatar_url}
|
||||||
|
className={styles.avatar}
|
||||||
|
width={256}
|
||||||
|
height={256}
|
||||||
|
alt={`${user.full_name}'s avatar`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="column col-8 col-md-12 col-mx-auto">
|
||||||
|
<h1>{user.full_name}</h1>
|
||||||
|
|
||||||
|
<h3>{user.description}</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
href={`https://${giteaServerUrl}/${user.login}`}
|
||||||
|
className="btn btn-primary mr-2"
|
||||||
|
>
|
||||||
|
Git
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href={`mailto:${user.email}`} className="btn btn-primary">
|
||||||
|
Contact
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-gray">
|
||||||
|
Availibility: {isAvailable && "Available"}
|
||||||
|
{!isAvailable && "Not available"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default User;
|
@ -1,3 +0,0 @@
|
|||||||
.main {
|
|
||||||
padding-top: 10rem;
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
.main {
|
||||||
|
padding-top: 10rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarContainer {
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarCol {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
@ -1,124 +0,0 @@
|
|||||||
export interface GithubAPIRepository {
|
|
||||||
id: number;
|
|
||||||
node_id: string;
|
|
||||||
name: string;
|
|
||||||
full_name: string;
|
|
||||||
private: boolean;
|
|
||||||
owner: Owner;
|
|
||||||
html_url: string;
|
|
||||||
description: null | string;
|
|
||||||
fork: boolean;
|
|
||||||
url: string;
|
|
||||||
forks_url: string;
|
|
||||||
keys_url: string;
|
|
||||||
collaborators_url: string;
|
|
||||||
teams_url: string;
|
|
||||||
hooks_url: string;
|
|
||||||
issue_events_url: string;
|
|
||||||
events_url: string;
|
|
||||||
assignees_url: string;
|
|
||||||
branches_url: string;
|
|
||||||
tags_url: string;
|
|
||||||
blobs_url: string;
|
|
||||||
git_tags_url: string;
|
|
||||||
git_refs_url: string;
|
|
||||||
trees_url: string;
|
|
||||||
statuses_url: string;
|
|
||||||
languages_url: string;
|
|
||||||
stargazers_url: string;
|
|
||||||
contributors_url: string;
|
|
||||||
subscribers_url: string;
|
|
||||||
subscription_url: string;
|
|
||||||
commits_url: string;
|
|
||||||
git_commits_url: string;
|
|
||||||
comments_url: string;
|
|
||||||
issue_comment_url: string;
|
|
||||||
contents_url: string;
|
|
||||||
compare_url: string;
|
|
||||||
merges_url: string;
|
|
||||||
archive_url: string;
|
|
||||||
downloads_url: string;
|
|
||||||
issues_url: string;
|
|
||||||
pulls_url: string;
|
|
||||||
milestones_url: string;
|
|
||||||
notifications_url: string;
|
|
||||||
labels_url: string;
|
|
||||||
releases_url: string;
|
|
||||||
deployments_url: string;
|
|
||||||
created_at: Date;
|
|
||||||
updated_at: Date;
|
|
||||||
pushed_at: Date;
|
|
||||||
git_url: string;
|
|
||||||
ssh_url: string;
|
|
||||||
clone_url: string;
|
|
||||||
svn_url: string;
|
|
||||||
homepage: null | string;
|
|
||||||
size: number;
|
|
||||||
stargazers_count: number;
|
|
||||||
watchers_count: number;
|
|
||||||
language: null | string;
|
|
||||||
has_issues: boolean;
|
|
||||||
has_projects: boolean;
|
|
||||||
has_downloads: boolean;
|
|
||||||
has_wiki: boolean;
|
|
||||||
has_pages: boolean;
|
|
||||||
forks_count: number;
|
|
||||||
mirror_url: null;
|
|
||||||
archived: boolean;
|
|
||||||
disabled: boolean;
|
|
||||||
open_issues_count: number;
|
|
||||||
license: License | null;
|
|
||||||
allow_forking: boolean;
|
|
||||||
is_template: boolean;
|
|
||||||
web_commit_signoff_required: boolean;
|
|
||||||
topics: string[];
|
|
||||||
visibility: string;
|
|
||||||
forks: number;
|
|
||||||
open_issues: number;
|
|
||||||
watchers: number;
|
|
||||||
default_branch: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface License {
|
|
||||||
key: string;
|
|
||||||
name: string;
|
|
||||||
spdx_id: string;
|
|
||||||
url: string;
|
|
||||||
node_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Owner {
|
|
||||||
login: string;
|
|
||||||
id: number;
|
|
||||||
node_id: string;
|
|
||||||
avatar_url: string;
|
|
||||||
gravatar_id: string;
|
|
||||||
url: string;
|
|
||||||
html_url: string;
|
|
||||||
followers_url: string;
|
|
||||||
following_url: string;
|
|
||||||
gists_url: string;
|
|
||||||
starred_url: string;
|
|
||||||
subscriptions_url: string;
|
|
||||||
organizations_url: string;
|
|
||||||
repos_url: string;
|
|
||||||
events_url: string;
|
|
||||||
received_events_url: string;
|
|
||||||
type: string;
|
|
||||||
site_admin: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RecentRepository {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
url: string;
|
|
||||||
homepage?: string;
|
|
||||||
stargazers_count: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BestRepository extends RecentRepository {
|
|
||||||
forks_count: number;
|
|
||||||
language: string;
|
|
||||||
open_issues_count: number;
|
|
||||||
pushed_at: Date;
|
|
||||||
}
|
|
@ -0,0 +1,28 @@
|
|||||||
|
import z from "zod";
|
||||||
|
|
||||||
|
export const RepositoryResponse = z.object({
|
||||||
|
full_name: z.string(),
|
||||||
|
html_url: z.string(),
|
||||||
|
language: z.string(),
|
||||||
|
website: z.string(),
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string(),
|
||||||
|
forks_count: z.number(),
|
||||||
|
open_issues_count: z.number(),
|
||||||
|
description: z.string(),
|
||||||
|
size: z.number()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SearchResultsResponse = z.object({
|
||||||
|
ok: z.boolean(),
|
||||||
|
data: RepositoryResponse.array()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const UserResponse = z.object({
|
||||||
|
id: z.number(),
|
||||||
|
login: z.string(),
|
||||||
|
email: z.string(),
|
||||||
|
avatar_url: z.string(),
|
||||||
|
full_name: z.string(),
|
||||||
|
description: z.string()
|
||||||
|
});
|
@ -0,0 +1,5 @@
|
|||||||
|
export const giteaServerUrl =
|
||||||
|
process.env.NEXT_PUBLIC_GITEA_SERVER ?? "https://git.guusvanmeerveld.dev";
|
||||||
|
|
||||||
|
export const giteaUsername =
|
||||||
|
process.env.NEXT_PUBLIC_GITEA_USERNAME ?? "Guusvanmeerveld";
|
@ -0,0 +1,52 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import z from "zod";
|
||||||
|
|
||||||
|
import createConfigCatClient from "./createConfigCatClient";
|
||||||
|
|
||||||
|
import {
|
||||||
|
RepositoryResponse,
|
||||||
|
SearchResultsResponse,
|
||||||
|
UserResponse
|
||||||
|
} from "@models/responses";
|
||||||
|
import { giteaServerUrl } from "./config";
|
||||||
|
|
||||||
|
const apiUrl = `https://${giteaServerUrl}/api/v1`;
|
||||||
|
|
||||||
|
export const fetchAvailability = async (): Promise<boolean> => {
|
||||||
|
const configCatClient = createConfigCatClient();
|
||||||
|
|
||||||
|
const isAvailable: boolean =
|
||||||
|
(await configCatClient?.getValueAsync("amiavailable", true)) ?? true;
|
||||||
|
|
||||||
|
return isAvailable;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchUser = async (
|
||||||
|
giteaUsername: string
|
||||||
|
): Promise<z.infer<typeof UserResponse>> => {
|
||||||
|
const { data: user } = await axios.get<unknown>(
|
||||||
|
`${apiUrl}/users/${giteaUsername}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return UserResponse.parse(user);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchRepositories = async (
|
||||||
|
giteaUserUid: number
|
||||||
|
): Promise<z.infer<typeof RepositoryResponse>[]> => {
|
||||||
|
const { data: repositories } = await axios.get<unknown>(
|
||||||
|
`${apiUrl}/repos/search`,
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
topic: true,
|
||||||
|
q: "on-portfolio",
|
||||||
|
id: giteaUserUid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const results = SearchResultsResponse.parse(repositories);
|
||||||
|
|
||||||
|
if (results.ok) return results.data;
|
||||||
|
else throw results.data;
|
||||||
|
};
|
Loading…
Reference in new issue