mirror of
https://gitea.gofwd.group/dstrawsb/ballistic-builder.git
synced 2025-12-06 02:36:44 -05:00
before react 19 upgrade
This commit is contained in:
@@ -1,44 +1,49 @@
|
||||
"use server";
|
||||
import { eq, not , asc} from "drizzle-orm";
|
||||
import { eq, asc} from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { db } from "@db/index";
|
||||
import { accounts } from "@schemas/schema";
|
||||
import { vw_accounts } from "@schemas/schema";
|
||||
import { users } from "@schemas/schema";
|
||||
|
||||
export const getData = async () => {
|
||||
const data = await db.select().from(accounts).orderBy(asc(accounts.userId));
|
||||
export const getAllUsers = async () => {
|
||||
const data = await db.select().from(users).orderBy(asc(users.email));
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getAllAccounts = async () => {
|
||||
return getData();
|
||||
return getAllUsers();
|
||||
};
|
||||
|
||||
export const getViewAccounts = async () => {
|
||||
const data = await db.select().from(vw_accounts).orderBy(asc(vw_accounts.last_name));
|
||||
return data;
|
||||
export const getUser = async (userId : string) => {
|
||||
const data = await db.select().from(users).where(eq(users.id, userId));
|
||||
return data[0];
|
||||
};
|
||||
|
||||
export const addAccount = async ( first_name: string, last_name: string, username: string, email: string, password_hash : string) => {
|
||||
/* await db.insert(accounts).values({
|
||||
first_name : first_name, last_name: last_name, username: username, password_hash : password_hash
|
||||
}); */
|
||||
export const addUser = async ( first_name: string, last_name: string, username: string, email: string, hashedPassword : string) => {
|
||||
await db.insert(users).values({
|
||||
id: crypto.randomUUID(),
|
||||
first_name: first_name,
|
||||
last_name: last_name,
|
||||
username: username,
|
||||
hashedPassword: hashedPassword,
|
||||
email: email
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAccount = async (id: number) => {
|
||||
await db.delete(accounts).where(eq(accounts.userId, id));
|
||||
export const deleteUser = async (id: string) => {
|
||||
await db.delete(users).where(eq(users.id, id));
|
||||
revalidatePath("/");
|
||||
};
|
||||
|
||||
export const editAccount = async (id: number, first_name: string, last_name: string, username: string, email : string, password_hash: string) => {
|
||||
export const editUser = async (id: string, first_name: string, last_name: string, username: string, email : string, hashedPassword: string) => {
|
||||
await db
|
||||
.update(accounts)
|
||||
.update(users)
|
||||
.set({
|
||||
first_name : first_name,
|
||||
last_name: last_name,
|
||||
username: username,
|
||||
email: email,
|
||||
password_hash: password_hash
|
||||
hashedPassword: hashedPassword
|
||||
})
|
||||
.where(eq(accounts.userId, id));
|
||||
.where(eq(users.id, id));
|
||||
revalidatePath("/");
|
||||
};
|
||||
@@ -18,7 +18,6 @@ export default async function AccountsPage() {
|
||||
return (
|
||||
<div>
|
||||
<PageHero title="Accounts" />
|
||||
|
||||
<div className="container mx-auto">
|
||||
<Suspense fallback="Loading...">
|
||||
<AccountsTable data={data} newColumnHeadings={columnHeadings}></AccountsTable>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { users } from "@schemas/schema";
|
||||
import { getData } from "@actions/accountActions";
|
||||
|
||||
import UserForm from "@components/Account/UserForm";
|
||||
import { getUser } from "@/actions/accountActions";
|
||||
import { validateRequest } from "@/lib/wdcStarter/auth";
|
||||
|
||||
export default async function MyAccountsPage() {
|
||||
const data = await getData();
|
||||
const {session, user} = await validateRequest();
|
||||
const theUser = session?.userId ? await getUser(session.userId.toString()) : null;
|
||||
return (
|
||||
<div className="bg-gray-100 min-h-screen flex flex-col">
|
||||
<div>
|
||||
My account Page
|
||||
</div>
|
||||
{/* <Account account={data} /> */}
|
||||
<UserForm user={user} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
92
src/app/components/Account/UserForm.tsx
Normal file
92
src/app/components/Account/UserForm.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
'use client';
|
||||
import React, { useState, ChangeEvent, FormEvent } from "react";
|
||||
import {users} from "@schemas/schema"
|
||||
interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
emailVerified: string | null;
|
||||
image: string | null;
|
||||
}
|
||||
|
||||
interface UserFormProps {
|
||||
user: typeof users;
|
||||
onSave: (user: typeof users) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const UserForm: React.FC<UserFormProps> = ({ user, onSave, onCancel }) => {
|
||||
const [formData, setFormData] = useState<typeof users>(user);
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData({ ...formData, [name]: value });
|
||||
};
|
||||
|
||||
const handleSubmit = (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
onSave(formData);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
className="mt-1 block w-full border border-gray-300 rounded-md shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="emailVerified" className="block text-sm font-medium text-gray-700">
|
||||
Email Verified
|
||||
</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
name="emailVerified"
|
||||
id="emailVerified"
|
||||
value={formData.emailVerified || ""}
|
||||
onChange={handleChange}
|
||||
className="mt-1 block w-full border border-gray-300 rounded-md shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="image" className="block text-sm font-medium text-gray-700">
|
||||
Image
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="image"
|
||||
id="image"
|
||||
value={formData.image || ""}
|
||||
onChange={handleChange}
|
||||
className="mt-1 block w-full border border-gray-300 rounded-md shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end space-x-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCancel}
|
||||
className="px-4 py-2 bg-gray-300 text-gray-700 rounded-md"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-md"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserForm;
|
||||
@@ -154,11 +154,7 @@ export default function PopNavDialog(props:any) {
|
||||
<div className="grid grid-cols-2 gap-x-4">
|
||||
{category.featured.map((item) => (
|
||||
<div key={item.name} className="group relative text-sm">
|
||||
<img
|
||||
alt={item.imageAlt}
|
||||
src={item.imageSrc}
|
||||
className="aspect-square w-full rounded-lg bg-gray-100 object-cover group-hover:opacity-75"
|
||||
/>
|
||||
<img alt={item.imageAlt} src={item.imageSrc} className="aspect-square w-full rounded-lg bg-gray-100 object-cover group-hover:opacity-75"/>
|
||||
<a
|
||||
href={item.href}
|
||||
className="mt-6 block font-medium text-gray-900"
|
||||
@@ -377,7 +373,7 @@ export default function PopNavDialog(props:any) {
|
||||
<div className="ml-auto flex items-center">
|
||||
<div className="hidden lg:flex lg:flex-1 lg:items-center lg:justify-end lg:space-x-6">
|
||||
<a
|
||||
href={linkPath} onClick={async (e) => {e.preventDefault; console.log("in the onclick"); await logout()} } className="text-sm font-medium text-gray-700 hover:text-gray-800">
|
||||
href={linkPath} onClick={async (e) => {e.preventDefault(); console.log("in the onclick"); await logout()} } className="text-sm font-medium text-gray-700 hover:text-gray-800">
|
||||
{user == null?"Sign In": "Log Out"}
|
||||
</a>
|
||||
<span aria-hidden="true" className="h-6 w-px bg-gray-200" />
|
||||
|
||||
@@ -21,7 +21,7 @@ export default function RootLayout(props: { children: React.ReactNode }) {
|
||||
const { children } = props;
|
||||
|
||||
return (
|
||||
/* <ClerkProvider> */
|
||||
|
||||
<html lang="en" suppressHydrationWarning className={""}>
|
||||
<body className="bg-slate-200 ">
|
||||
<header>
|
||||
@@ -40,6 +40,6 @@ export default function RootLayout(props: { children: React.ReactNode }) {
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
/* </ClerkProvider> */
|
||||
|
||||
)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ export default async function AccountsTable( props: any ) {
|
||||
<div className="mt-8 flow-root">
|
||||
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||
<Suspense fallback={<Loading />}>
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -66,7 +67,7 @@ export default async function AccountsTable( props: any ) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className=" divide-y divide-gray-200 bg-white">
|
||||
<Suspense fallback={<Loading />}>
|
||||
|
||||
{props.data.map((item: any) => (
|
||||
<tr key={item.uuid}>
|
||||
<td className="whitespace-wrap flex items-center py-4 pl-4 pr-3 text-xs font-medium text-gray-900 ">
|
||||
@@ -97,10 +98,10 @@ export default async function AccountsTable( props: any ) {
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</Suspense>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
0
src/components/Aco
Normal file
0
src/components/Aco
Normal file
@@ -5,40 +5,40 @@ import { isAdmin } from "@/actions/userActions";
|
||||
|
||||
const navigation = {
|
||||
armory: [
|
||||
{ name: 'Builder', href: '/Builder', role: null },
|
||||
{ name: 'Lowers', href: '/Products/lowers', role: null },
|
||||
{ name: 'Uppers', href: '/Products/uppers', role: null },
|
||||
{ name: 'Optics', href: '/Products/optics', role: null },
|
||||
{ name: 'Accessories', href: '/Products/accessories', role: null },
|
||||
{ name: 'Suppressors', href: '/Products/suppressors', role: null },
|
||||
{ name: 'Builder', href: '/Builder', role: "All" },
|
||||
{ name: 'Lowers', href: '/Products/lowers', role: "All" },
|
||||
{ name: 'Uppers', href: '/Products/uppers', role: "All" },
|
||||
{ name: 'Optics', href: '/Products/optics', role: "All" },
|
||||
{ name: 'Accessories', href: '/Products/accessories', role: "All" },
|
||||
{ name: 'Suppressors', href: '/Products/suppressors', role: "All" },
|
||||
],
|
||||
admin: [
|
||||
{ name: 'Users', href: '/Admin/Users', role: "Admin" },
|
||||
{ name: 'Accounts', href: '/Admin/Accounts', role: "Admin" },
|
||||
],
|
||||
account: [
|
||||
{ name: 'Accounts', href: '/Admin/Accounts', role: null },
|
||||
{ name: 'My Account', href: '/MyAccount', role: null },
|
||||
{ name: 'Register', href: '/login', role: null },
|
||||
{ name: 'Guides', href: '/Guides', role: null },
|
||||
{ name: 'My Account', href: '/MyAccount', role: "All" },
|
||||
{ name: 'Register', href: '/login', role: "All" },
|
||||
{ name: 'Guides', href: '/Guides', role: "All" },
|
||||
],
|
||||
about: [
|
||||
{ name: 'About', href: '/About', role: null },
|
||||
{ name: 'Blog', href: '/Blog', role: null },
|
||||
{ name: 'Jobs', href: '/Jobs', role: null },
|
||||
{ name: 'Press', href: '/Press', role: null },
|
||||
{ name: 'Contact', href: '/Contact', role: null },
|
||||
{ name: 'About', href: '/About', role: "All" },
|
||||
{ name: 'Blog', href: '/Blog', role: "All" },
|
||||
{ name: 'Jobs', href: '/Jobs', role: "All" },
|
||||
{ name: 'Press', href: '/Press', role: "All" },
|
||||
{ name: 'Contact', href: '/Contact', role: "All" },
|
||||
],
|
||||
legal: [
|
||||
{ name: 'Terms of service', href: '/TOS', role: null },
|
||||
{ name: 'Privacy policy', href: '/PP', role: null },
|
||||
{ name: 'Affiliate Disclosure', href: '/Disclosure', role: null },
|
||||
{ name: 'Terms of service', href: '/TOS', role: "All" },
|
||||
{ name: 'Privacy policy', href: '/PP', role: "All" },
|
||||
{ name: 'Affiliate Disclosure', href: '/Disclosure', role: "All" },
|
||||
],
|
||||
social: [
|
||||
{
|
||||
name: 'Facebook',
|
||||
href: '#',
|
||||
role: null,
|
||||
icon: (props: any) => (
|
||||
role: "All",
|
||||
icon: (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -51,8 +51,8 @@ const navigation = {
|
||||
{
|
||||
name: 'Instagram',
|
||||
href: '#',
|
||||
role: null,
|
||||
icon: (props: any) => (
|
||||
role: "All",
|
||||
icon: (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -65,8 +65,8 @@ const navigation = {
|
||||
{
|
||||
name: 'X',
|
||||
href: '#',
|
||||
role: null,
|
||||
icon: (props: any) => (
|
||||
role: "All",
|
||||
icon: (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" {...props}>
|
||||
<path d="M13.6823 10.6218L20.2391 3H18.6854L12.9921 9.61788L8.44486 3H3.2002L10.0765 13.0074L3.2002 21H4.75404L10.7663 14.0113L15.5685 21H20.8131L13.6819 10.6218H13.6823ZM11.5541 13.0956L10.8574 12.0991L5.31391 4.16971H7.70053L12.1742 10.5689L12.8709 11.5655L18.6861 19.8835H16.2995L11.5541 13.096V13.0956Z" />
|
||||
</svg>
|
||||
@@ -75,8 +75,8 @@ const navigation = {
|
||||
{
|
||||
name: 'YouTube',
|
||||
href: '#',
|
||||
role: null,
|
||||
icon: (props: any) => (
|
||||
role: "All",
|
||||
icon: (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -95,8 +95,7 @@ export default async function Footer() {
|
||||
const { session, user } = await validateRequest();
|
||||
const userId = user?.id ?? '';
|
||||
let hasAdminFlag:boolean = false;
|
||||
console.log("console log:"+ userId);
|
||||
console.log(user?.email);
|
||||
|
||||
if(session != null) {
|
||||
hasAdminFlag = (await isAdmin(userId)) ?? false;
|
||||
console.log("admin?:" + hasAdminFlag);
|
||||
@@ -106,7 +105,7 @@ export default async function Footer() {
|
||||
|
||||
return (
|
||||
<footer className="bg-zinc-900">
|
||||
<div className="bg-white">{userId}should be something here</div>
|
||||
<div className="bg-white"></div>
|
||||
<div className="mx-auto max-w-7xl px-6 pb-8 pt-20 sm:pt-24 lg:px-8 lg:pt-32">
|
||||
<div className="xl:grid xl:grid-cols-3 xl:gap-8">
|
||||
<div className="grid grid-cols-2 gap-8 xl:col-span-2">
|
||||
@@ -213,7 +212,7 @@ export default async function Footer() {
|
||||
{navigation.social.map((item) => (
|
||||
<a key={item.name} href={item.href} className="text-gray-400 hover:text-gray-300">
|
||||
<span className="sr-only">{item.name}</span>
|
||||
<item.icon aria-hidden="true" className="size-6" />
|
||||
<item.icon aria-hidden="true" className={"size-6"} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { clerkMiddleware } from "@clerk/nextjs/server";
|
||||
|
||||
export default clerkMiddleware();
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
@@ -17,7 +14,7 @@ import { verifyRequestOrigin } from "lucia";
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
export async function middleware(request: NextRequest): Promise<NextResponse> {
|
||||
export default async function middleware(request: NextRequest): Promise<NextResponse> {
|
||||
if (request.method === "GET") {
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user