Some frontend improvements / bd testing was cpmpleted
This commit is contained in:
parent
6b4fe31d67
commit
ae9bd6f9d6
@ -1,53 +1,20 @@
|
||||
import "./App.css";
|
||||
import "@radix-ui/themes/styles.css";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Callout,
|
||||
Container,
|
||||
Flex,
|
||||
Separator,
|
||||
Text,
|
||||
Theme,
|
||||
ThemePanel,
|
||||
} from "@radix-ui/themes";
|
||||
|
||||
import {
|
||||
Router,
|
||||
Route,
|
||||
createBrowserRouter,
|
||||
createRoutesFromElements,
|
||||
RouterProvider,
|
||||
Routes,
|
||||
useRouteError,
|
||||
} from "react-router-dom";
|
||||
import MainPage from "./Pages/MainPage/MainPage";
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import queryClient from "./api/QueryClient/QueryClient";
|
||||
|
||||
function ErrorBoundary() {
|
||||
let error = useRouteError();
|
||||
console.error(error);
|
||||
|
||||
return <div>Dang! This route does not exist... Yet ;)</div>;
|
||||
}
|
||||
import { routes } from "./routes/routes";
|
||||
|
||||
const router = createBrowserRouter(
|
||||
createRoutesFromElements(
|
||||
<>
|
||||
<Route
|
||||
path="/"
|
||||
errorElement={<ErrorBoundary />}
|
||||
element={<MainPage />}
|
||||
>
|
||||
<Route index element={<Text>Cringer path</Text>} />
|
||||
<Route
|
||||
path="/a?/c"
|
||||
element={<Text>Cringer path, but this a</Text>}
|
||||
></Route>
|
||||
</Route>
|
||||
</>
|
||||
)
|
||||
routes
|
||||
);
|
||||
|
||||
export default function App() {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Button, Text } from "@radix-ui/themes";
|
||||
import { Button, Card, ChevronDownIcon, Text } from "@radix-ui/themes";
|
||||
import * as NavigationMenu from "@radix-ui/react-navigation-menu";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
@ -14,6 +14,27 @@ export default function NavBar() {
|
||||
|
||||
<NavItem text="C-Cringer" to="/c" />
|
||||
|
||||
<NavigationMenu.Item className="text-center">
|
||||
<NavigationMenu.Trigger className="flex items-center">
|
||||
<Button
|
||||
asChild
|
||||
className="w-fit h-fit rounded-full m-0 p-0 pr-2 pl-2 mt-2 mb-2 duration-[50ms]"
|
||||
variant="ghost"
|
||||
highContrast
|
||||
>
|
||||
<Text
|
||||
size={"3"}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
Cringer 123 <ChevronDownIcon />
|
||||
</Text>
|
||||
</Button>
|
||||
</NavigationMenu.Trigger>
|
||||
|
||||
<NavigationMenu.Content className="absolute data-[motion=from-start]:scale-150">
|
||||
<Card>asd</Card>
|
||||
</NavigationMenu.Content>
|
||||
</NavigationMenu.Item>
|
||||
</NavigationMenu.List>
|
||||
</NavigationMenu.Root>
|
||||
</nav>
|
||||
@ -26,22 +47,16 @@ type TNavItem = {
|
||||
};
|
||||
|
||||
function NavItem(props: TNavItem) {
|
||||
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
console.log(location);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<NavigationMenu.Item>
|
||||
<NavigationMenu.Link>
|
||||
<Button
|
||||
className="w-fit h-fit rounded-full m-0 p-0 pr-2 pl-2 mt-2 mb-2"
|
||||
|
||||
className="w-fit h-fit rounded-full m-0 p-0 pr-2 pl-2 mt-2 mb-2 duration-[50ms]"
|
||||
highContrast
|
||||
|
||||
variant={location.pathname === props.to ? 'solid' : 'ghost'}
|
||||
variant={location.pathname === props.to ? "solid" : "ghost"}
|
||||
onClick={() => navigate(props.to)}
|
||||
>
|
||||
<Text size={"3"}>{props.text}</Text>
|
||||
|
||||
27
enshi/src/routes/routes.tsx
Normal file
27
enshi/src/routes/routes.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { createRoutesFromElements, Route, useRouteError } from "react-router-dom"
|
||||
import MainPage from "../Pages/MainPage/MainPage"
|
||||
import {Text} from "@radix-ui/themes";
|
||||
|
||||
|
||||
function ErrorBoundary() {
|
||||
let error = useRouteError();
|
||||
console.error(error);
|
||||
|
||||
return <div>Dang! This route does not exist... Yet ;)</div>;
|
||||
}
|
||||
|
||||
export const routes = createRoutesFromElements(
|
||||
<>
|
||||
<Route
|
||||
path="/"
|
||||
errorElement={<ErrorBoundary />}
|
||||
element={<MainPage />}
|
||||
>
|
||||
<Route index element={<Text>Cringer path</Text>} />
|
||||
<Route
|
||||
path="/a?/c"
|
||||
element={<Text>Cringer path, but this a</Text>}
|
||||
></Route>
|
||||
</Route>
|
||||
</>
|
||||
)
|
||||
@ -5,7 +5,16 @@ content: [
|
||||
"./src/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
animation: {
|
||||
'appear': 'appear 0.25s'
|
||||
},
|
||||
keyframes: {
|
||||
appear: {
|
||||
'100%': {opacity: '1'}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
44
enshi_back/db/go_queries/favorites_queries.sql.go
Normal file
44
enshi_back/db/go_queries/favorites_queries.sql.go
Normal file
@ -0,0 +1,44 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: favorites_queries.sql
|
||||
|
||||
package db_repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const createFavorite = `-- name: CreateFavorite :one
|
||||
INSERT INTO public.favorites
|
||||
(user_id, blog_id, favorited_at)
|
||||
VALUES($1, $2, CURRENT_TIMESTAMP)
|
||||
RETURNING user_id, blog_id, favorited_at
|
||||
`
|
||||
|
||||
type CreateFavoriteParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
BlogID int64 `json:"blog_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateFavorite(ctx context.Context, arg CreateFavoriteParams) (Favorite, error) {
|
||||
row := q.db.QueryRow(ctx, createFavorite, arg.UserID, arg.BlogID)
|
||||
var i Favorite
|
||||
err := row.Scan(&i.UserID, &i.BlogID, &i.FavoritedAt)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteFavorite = `-- name: DeleteFavorite :exec
|
||||
DELETE FROM public.favorites
|
||||
WHERE user_id=$1 AND blog_id=$2
|
||||
`
|
||||
|
||||
type DeleteFavoriteParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
BlogID int64 `json:"blog_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteFavorite(ctx context.Context, arg DeleteFavoriteParams) error {
|
||||
_, err := q.db.Exec(ctx, deleteFavorite, arg.UserID, arg.BlogID)
|
||||
return err
|
||||
}
|
||||
48
enshi_back/db/go_queries/multi_queries.sql.go
Normal file
48
enshi_back/db/go_queries/multi_queries.sql.go
Normal file
@ -0,0 +1,48 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: multi_queries.sql
|
||||
|
||||
package db_repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const getFavoriteBlogsInfosByUserId = `-- name: GetFavoriteBlogsInfosByUserId :many
|
||||
SELECT blogs.blog_id, blogs.user_id, blogs.title, blogs.description, blogs.category_id, blogs.created_at
|
||||
FROM favorites
|
||||
JOIN blogs on blogs.blog_id = favorites.blog_id
|
||||
WHERE favorites.user_id = $1
|
||||
`
|
||||
|
||||
type GetFavoriteBlogsInfosByUserIdRow struct {
|
||||
Blog Blog `json:"blog"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetFavoriteBlogsInfosByUserId(ctx context.Context, userID int64) ([]GetFavoriteBlogsInfosByUserIdRow, error) {
|
||||
rows, err := q.db.Query(ctx, getFavoriteBlogsInfosByUserId, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetFavoriteBlogsInfosByUserIdRow
|
||||
for rows.Next() {
|
||||
var i GetFavoriteBlogsInfosByUserIdRow
|
||||
if err := rows.Scan(
|
||||
&i.Blog.BlogID,
|
||||
&i.Blog.UserID,
|
||||
&i.Blog.Title,
|
||||
&i.Blog.Description,
|
||||
&i.Blog.CategoryID,
|
||||
&i.Blog.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@ -25,4 +25,6 @@ CREATE TABLE "public"."post_tags" ("post_id" bigint NOT NULL, "tag_id" integer N
|
||||
-- Create "post_votes" table
|
||||
CREATE TABLE "public"."post_votes" ("post_id" bigint NOT NULL, "user_id" bigint NOT NULL, "vote" boolean NOT NULL, PRIMARY KEY ("post_id", "user_id"), CONSTRAINT "post_votes_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "post_votes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE NO ACTION);
|
||||
-- Create "profiles" table
|
||||
CREATE TABLE "public"."profiles" ("profile_id" bigint NOT NULL, "user_id" bigint NULL, "bio" text NULL, "avatar_url" character varying(255) NULL, "website_url" character varying(100) NULL, PRIMARY KEY ("profile_id"), CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
||||
CREATE TABLE "public"."profiles" ("profile_id" bigint NOT NULL, "user_id" bigint NOT NULL, "bio" text NULL, "avatar_url" character varying(255) NULL, "website_url" character varying(100) NULL, PRIMARY KEY ("profile_id"), CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
||||
-- Create index "profiles_user_id_idx" to table: "profiles"
|
||||
CREATE UNIQUE INDEX "profiles_user_id_idx" ON "public"."profiles" ("user_id");
|
||||
|
||||
9
enshi_back/db/queries/favorites_queries.sql
Normal file
9
enshi_back/db/queries/favorites_queries.sql
Normal file
@ -0,0 +1,9 @@
|
||||
-- name: CreateFavorite :one
|
||||
INSERT INTO public.favorites
|
||||
(user_id, blog_id, favorited_at)
|
||||
VALUES($1, $2, CURRENT_TIMESTAMP)
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteFavorite :exec
|
||||
DELETE FROM public.favorites
|
||||
WHERE user_id=$1 AND blog_id=$2;
|
||||
6
enshi_back/db/queries/multi_queries.sql
Normal file
6
enshi_back/db/queries/multi_queries.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- name: GetFavoriteBlogsInfosByUserId :many
|
||||
SELECT sqlc.embed(blogs)
|
||||
FROM favorites
|
||||
JOIN blogs on blogs.blog_id = favorites.blog_id
|
||||
WHERE favorites.user_id = $1;
|
||||
|
||||
@ -30,7 +30,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Transaction
|
||||
tx, _ := utils.Dbx_connection.Begin(context.Background())
|
||||
tx, _ := utils.Dbx.Begin(context.Background())
|
||||
defer tx.Rollback(context.Background())
|
||||
|
||||
repo := db_repo.New(tx)
|
||||
|
||||
@ -20,9 +20,9 @@ type Argon2Hash struct {
|
||||
}
|
||||
|
||||
type HashSalt struct {
|
||||
hash []byte
|
||||
Hash []byte
|
||||
salt []byte
|
||||
stringToStore string
|
||||
StringToStore string
|
||||
}
|
||||
|
||||
// Initializer for algorithm
|
||||
@ -75,7 +75,7 @@ func (a *Argon2Hash) HashGen(password, salt []byte) (*HashSalt, error) {
|
||||
stringToStore := fmt.Sprintf("$m=%d,t=%d$%s$%s", a.memory, a.time, saltDecoded, hashDecoded)
|
||||
|
||||
// This is unnecessary structure i created following the guide 0_0
|
||||
return &HashSalt{hash: hash, salt: salt, stringToStore: stringToStore}, nil
|
||||
return &HashSalt{Hash: hash, salt: salt, StringToStore: stringToStore}, nil
|
||||
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ func (a *Argon2Hash) Compare(hash, salt, password []byte) error {
|
||||
}
|
||||
|
||||
// Comparing hashes
|
||||
if !bytes.Equal(hash, hashSalt.hash) {
|
||||
if !bytes.Equal(hash, hashSalt.Hash) {
|
||||
return fmt.Errorf("invalid password (hashes does not match)")
|
||||
}
|
||||
|
||||
@ -153,6 +153,6 @@ func Test() {
|
||||
}
|
||||
|
||||
// fmt.Println(testDbString)
|
||||
fmt.Printf("%s", cringe.stringToStore)
|
||||
fmt.Printf("%s", cringe.StringToStore)
|
||||
fmt.Print("\n\n\n\n")
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ func registerUser(c *gin.Context) {
|
||||
|
||||
rowsToClose, errr := Dbx.Query(context.Background(), "INSERT INTO users "+
|
||||
"(user_id, username, user_name, user_password) "+
|
||||
"VALUES($1, $2, $3, $4);", newUuid, body.Username, body.Name, hashedPassword.stringToStore)
|
||||
"VALUES($1, $2, $3, $4);", newUuid, body.Username, body.Name, hashedPassword.StringToStore)
|
||||
|
||||
if errr != nil {
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"error": errr.Error()})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user