mirror of
https://gitea.gofwd.group/dstrawsb/ballistic-builder.git
synced 2025-12-06 02:36:44 -05:00
accounts table and many other fixes
This commit is contained in:
@@ -3,9 +3,18 @@ import { eq, not , 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";
|
||||
|
||||
export const getData = async () => {
|
||||
const data = await db.select().from(accounts).orderBy(asc(accounts.last_name));
|
||||
const data = await db.select().from(accounts).orderBy(asc(accounts.userId));
|
||||
return data;
|
||||
};
|
||||
export const getAllAccounts = async () => {
|
||||
return getData();
|
||||
};
|
||||
|
||||
export const getViewAccounts = async () => {
|
||||
const data = await db.select().from(vw_accounts).orderBy(asc(vw_accounts.last_name));
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,8 +3,12 @@ import { eq, not , asc} from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { db } from "../db";
|
||||
import { componentType } from "@schemas/schema";
|
||||
|
||||
export const getData = async () => {
|
||||
const data = await db.select().from(componentType).orderBy(asc(componentType.name));
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getComponentTypeName = async () => {
|
||||
return getData();
|
||||
};
|
||||
@@ -10,3 +10,6 @@ export const getData = async () => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getManufacturersName = async () => {
|
||||
return getData();
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ export const getData = async () => {
|
||||
const data = await db.select().from(users).orderBy(asc(users.last_name));
|
||||
return data;
|
||||
};
|
||||
export const getAllUsers = async () => {
|
||||
export const getAllUsersOrdrByLastname = async () => {
|
||||
const data = await db.select().from(users).orderBy(asc(users.last_name));
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ export default function Blog() {
|
||||
and exploring firearm parts. Designed for enthusiasts by
|
||||
enthusiasts, we make firearm building easy and accessible.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ export default function Disclosure() {
|
||||
and exploring firearm parts. Designed for enthusiasts by
|
||||
enthusiasts, we make firearm building easy and accessible.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -8,7 +8,6 @@ export default function Footer() {
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<p>© {new Date().getFullYear()} {constants.APP_NAME}. All rights reserved.</p>
|
||||
<p>Built by Forward Group ⚡</p>
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ export default function Jobs() {
|
||||
and exploring firearm parts. Designed for enthusiasts by
|
||||
enthusiasts, we make firearm building easy and accessible.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ export default function About() {
|
||||
and exploring firearm parts. Designed for enthusiasts by
|
||||
enthusiasts, we make firearm building easy and accessible.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ export default function TOS() {
|
||||
and exploring firearm parts. Designed for enthusiasts by
|
||||
enthusiasts, we make firearm building easy and accessible.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
import { accounts } from "@schemas/schema";
|
||||
import { getData } from "@actions/accountActions";
|
||||
import Account from "@components/Account"; // Adjust the import path as necessary
|
||||
import React from 'react';
|
||||
import { getViewAccounts } from "@actions/accountActions";
|
||||
import AccountsTable from "@src/components/AccountsTable"; // Adjust the import path as necessary
|
||||
import React, { Suspense } from 'react';
|
||||
import { ColumnHeadings } from "@src/lib/utils";
|
||||
import PageHero from "@src/components/PageHero";
|
||||
|
||||
|
||||
export interface AccountProps {
|
||||
account: any; // Adjust the type according to your data structure
|
||||
}
|
||||
|
||||
|
||||
export default async function AccountsPage() {
|
||||
const data = await getData();
|
||||
const columnHeadings = new ColumnHeadings([
|
||||
"First Name",
|
||||
"Last Name",
|
||||
"Actions",
|
||||
]);
|
||||
const data = await getViewAccounts();
|
||||
return (
|
||||
<div className="bg-gray-100 min-h-screen flex flex-col">
|
||||
<Account account={data} />
|
||||
<div>
|
||||
<PageHero title="Accounts" />
|
||||
|
||||
<div className="container mx-auto">
|
||||
<Suspense fallback="Loading...">
|
||||
<AccountsTable data={data} newColumnHeadings={columnHeadings}></AccountsTable>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export default async function UsersPage() {
|
||||
const data = await getData();
|
||||
|
||||
|
||||
const columnHeadings = new ColumnHeadings(['E-mail Address', 'First Name', 'Last Name', 'Blank']);
|
||||
const columnHeadings = new ColumnHeadings(['E-mail Address', 'First Name', 'Last Name', 'User Name']);
|
||||
return (
|
||||
<div>
|
||||
<PageHero title="Users" />
|
||||
|
||||
18
src/app/Products/optics/page.tsx
Normal file
18
src/app/Products/optics/page.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { getOptics } from "@queries/PSA";
|
||||
import partTypes from 'src/data/parts_cats.json';
|
||||
import styles from '../styles.module.css';
|
||||
import PageHero from "@components/PageHero";
|
||||
import SortTable from "@components/SortTable";
|
||||
|
||||
export default async function OpticsPage() {
|
||||
const psa = await getOptics();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHero title="Optics" />
|
||||
<div className="container mx-auto">
|
||||
<SortTable data={psa}></SortTable>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { AccountProps } from "@src/app/Accounts/page";
|
||||
import React from "react";
|
||||
|
||||
|
||||
export const Account: React.FC<AccountProps> = ({ account }) => {
|
||||
return (
|
||||
<div className="account-card">
|
||||
<h2>{account.name}</h2>
|
||||
<p>{account.email}</p>
|
||||
{/* Add more fields as necessary */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default Account;
|
||||
106
src/components/AccountsTable/index.tsx
Normal file
106
src/components/AccountsTable/index.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import React from "react";
|
||||
import { ChevronDownIcon } from "@heroicons/react/20/solid";
|
||||
import { PlusCircleIcon } from "@heroicons/react/20/solid";
|
||||
import { ColumnHeadings } from "@src/lib/utils";
|
||||
import styles from '../styles.module.css';
|
||||
import PageHero from "@components/PageHero";
|
||||
|
||||
import { Suspense } from "react";
|
||||
import Loading from "@src/app/components/Loading/loading";
|
||||
import Link from "next/link";
|
||||
|
||||
export default async function AccountsTable( props: any ) {
|
||||
|
||||
return (
|
||||
<div className="pb-12">
|
||||
|
||||
<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">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
className="py-3.5 pl-4 pr-3 text-left text-xs font-semibold text-gray-900 "
|
||||
>
|
||||
<a href="#" className="group inline-flex">
|
||||
{props.newColumnHeadings.getHeading()}
|
||||
<span className="invisible ml-2 flex-none rounded text-gray-400 group-hover:visible group-focus:visible">
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className="size-5"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-xs font-semibold text-gray-900"
|
||||
>
|
||||
<a href="#" className="group inline-flex">
|
||||
{props.newColumnHeadings.getHeading()}
|
||||
<span className="ml-2 flex-none rounded bg-gray-100 text-gray-900 group-hover:bg-gray-200">
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className="size-5"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-xs font-semibold text-gray-900"
|
||||
>
|
||||
<a href="#" className="group inline-flex">
|
||||
{props.newColumnHeadings.getHeading()}
|
||||
<span className="ml-2 flex-none rounded bg-gray-100 text-gray-900 group-hover:bg-gray-200">
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className="size-5"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className=" divide-y divide-gray-200 bg-white">
|
||||
{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 ">
|
||||
|
||||
<Link href={`/userProfile/${item.uuid}`}><span className="pl-2"> {item.first_name}</span></Link>
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-xs text-gray-900">
|
||||
{item.last_name}
|
||||
</td>
|
||||
|
||||
|
||||
<td className="whitespace-nowrap px-3 py-4 text-xs text-gray-900">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-x-1.5 rounded-xl bg-lime-800 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-lime-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lime-900"
|
||||
>
|
||||
Edit
|
||||
<PlusCircleIcon
|
||||
aria-hidden="true"
|
||||
className="-mr-0.5 size-5"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
<td style={{display:'none'}}>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
import Header from "../Header";
|
||||
import Hero from "../Hero";
|
||||
import FeaturesSection from "../FeaturesSection";
|
||||
import About from "../../app/site/About/page";
|
||||
import Contact from "../../app/site/Contact/page";
|
||||
import Footer from "../../app/site/Footer/page";
|
||||
import About from "@siteInfo/About/page";
|
||||
import Contact from "@siteInfo/Contact/page";
|
||||
import Footer from "@siteInfo/Footer/page";
|
||||
|
||||
export default function HomeContent() {
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ export default async function UsersTable(props: any) {
|
||||
{item.last_name}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-xs text-gray-900">
|
||||
${item.username}
|
||||
{item.username}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-xs text-gray-900">
|
||||
<button
|
||||
|
||||
@@ -12,6 +12,7 @@ const navigation = {
|
||||
{ name: 'Users', href: '/Admin/Users' },
|
||||
],
|
||||
account: [
|
||||
{ name: 'Accounts', href: '/Accounts' },
|
||||
{ name: 'My Account', href: '/MyAccount' },
|
||||
{ name: 'Register', href: '/signin' },
|
||||
{ name: 'Guides', href: '/Guides' },
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// db/queries.ts
|
||||
"use server";
|
||||
import { eq, not , asc} from "drizzle-orm";
|
||||
import { accounts } from '@schemas/schema'
|
||||
import { db } from '../../index';
|
||||
import { accounts } from '@schemas/schema';
|
||||
import { vw_accounts } from '@schemas/schema';
|
||||
import { db } from '@db/index';
|
||||
|
||||
// Fetch all account
|
||||
export async function getAllAccounts() {
|
||||
return await db.select().from(accounts);
|
||||
}
|
||||
|
||||
//@TODO Accounts don't have these fields, i assume next.js auth code did it this way
|
||||
// Add a new account
|
||||
export async function addAcount(first_name: string, last_name : string, username : string, password_hash: string ) {
|
||||
return await db.insert(accounts).values({ first_name, last_name, username, password_hash }).returning();
|
||||
|
||||
@@ -102,6 +102,17 @@ export async function getStocks(page = 1) {
|
||||
.offset(offset);
|
||||
}
|
||||
|
||||
export async function getOptics(page = 1) {
|
||||
const limit = 40;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
return await db.select()
|
||||
.from(psa)
|
||||
.limit(limit)
|
||||
.where(and(like(psa.fineline, "%Optics%")))
|
||||
.offset(offset);
|
||||
}
|
||||
|
||||
export async function getStocksParts(page = 1) {
|
||||
const limit = 40;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { pgTable, integer, varchar, text, numeric, timestamp, unique, check, bigserial, date, boolean, uuid, bigint, real, doublePrecision, primaryKey } from "drizzle-orm/pg-core"
|
||||
import { pgTable, integer, varchar, text, numeric, timestamp, unique, check, bigserial, date, boolean, uuid, bigint, real, doublePrecision, primaryKey, pgView } from "drizzle-orm/pg-core"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
export const products = pgTable("products", {
|
||||
@@ -21,7 +21,7 @@ export const users = pgTable("users", {
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
username: varchar({ length: 50 }).notNull(),
|
||||
email: varchar({ length: 255 }).notNull(),
|
||||
emailVerifiedOn: timestamp("emailVerifiedOn", { mode: "date" }),
|
||||
emailVerifiedOn: timestamp("email_verified_on", { mode: "date" }),
|
||||
password_hash: varchar("password_hash", { length: 255 }).notNull(),
|
||||
first_name: varchar("first_name", { length: 50 }),
|
||||
last_name: varchar("last_name", { length: 50 }),
|
||||
@@ -425,10 +425,11 @@ export const authenticator = pgTable("authenticator", {
|
||||
});
|
||||
|
||||
export const accounts = pgTable("accounts", {
|
||||
userId: text().notNull(),
|
||||
uuid: uuid().defaultRandom(),
|
||||
userId: text("user_id").notNull(),
|
||||
type: text().notNull(),
|
||||
provider: text().notNull(),
|
||||
providerAccountId: text().notNull(),
|
||||
providerAccountId: text("provider_account_id").notNull(),
|
||||
refreshToken: text("refresh_token"),
|
||||
accessToken: text("access_token"),
|
||||
expiresAt: integer("expires_at"),
|
||||
@@ -441,3 +442,21 @@ export const accounts = pgTable("accounts", {
|
||||
accountProviderProviderAccountIdPk: primaryKey({ columns: [table.provider, table.providerAccountId], name: "account_provider_providerAccountId_pk"}),
|
||||
}
|
||||
});
|
||||
|
||||
export const vw_accounts = pgView("vw_accounts", {
|
||||
uuid: uuid().defaultRandom(),
|
||||
userId: text("user_id").notNull(),
|
||||
type: text().notNull(),
|
||||
provider: text().notNull(),
|
||||
providerAccountId: text("provider_account_id").notNull(),
|
||||
refreshToken: text("refresh_token"),
|
||||
accessToken: text("access_token"),
|
||||
expiresAt: integer("expires_at"),
|
||||
tokenType: text("token_type"),
|
||||
scope: text(),
|
||||
idToken: text("id_token"),
|
||||
sessionState: text("session_state"),
|
||||
first_name: text("first_name"),
|
||||
last_name: text("last_name"),
|
||||
|
||||
},).existing();
|
||||
Reference in New Issue
Block a user