Skip to content

Commit

Permalink
feat: type-safing the application, incomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
WomB0ComB0 committed Dec 6, 2023
1 parent 7564000 commit 4fa073f
Show file tree
Hide file tree
Showing 21 changed files with 375 additions and 44 deletions.
6 changes: 5 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
directory: "/server" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "npm" # See documentation for possible values
directory: "/frontend" # Location of package manifests
schedule:
interval: "weekly"
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"cmdk": "^0.2.0",
"date-fns": "^2.30.0",
"express": "^4.18.2",
"firebase": "^10.7.1",
"framer-motion": "^10.16.5",
"lucide-react": "^0.292.0",
"react": "^18.2.0",
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/build/footer/footerbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Footer as Foot } from '@/components/templates/index'

export const Footer = () => {
return (
<>
</>
)
}
18 changes: 3 additions & 15 deletions frontend/src/components/build/nav/nav-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ export const NavItem = ({
isActive,
onExpand,
}: NavItemProps) => {
const { user } = useContext(UserContext);

return (
<AccordionItem
value={user.id}
Expand All @@ -43,19 +41,9 @@ export const NavItem = ({
isActive && !isExpanded && "bg-sky-500/10 text-sky-700"
)}
>
<Div className="flex items-center gap-x-2">
<Div className="w-7 h-7 relative">
<Image
fill
src={user.avatar}
alt="User avatar"
className="rounded-sm object-cover"
/>
</Div>
<span className="font-medium text-sm">
{user.name}
</span>
</Div>
<>
Trigger
</>
</AccordionTrigger>
<AccordionContent className="pt-1 text-neutral-700">
<NavItems />
Expand Down
79 changes: 61 additions & 18 deletions frontend/src/components/custom/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,64 @@
import { CustomButtonProps } from '../../utils';
import { ShareIcon } from '../icons/components';
import { ShareIcon } from '@/components/icons/components';
import { Button, Link } from '@nextui-org/react';
import { cn } from '@/lib/utils';
import React, { ElementType } from 'react'
import { CustomButtonProps } from '@/types/frontend/custom-component';

const Button = ({title, containerStyles, link, textStyles, isDisabled, share}: CustomButtonProps) => {
const handleClick = () => {
if (link) {
window.open(link, '_blank');
}
};
const classes = {
button: '',
content: '',
label: '',
}

return (
<button disabled={isDisabled} type="button" className={`custom-btn ${containerStyles}`} onClick={handleClick}>
<span className={`button-text ${textStyles}`}>
{title}
</span>
{share ? <ShareIcon/> : null}
</button>
);
};
export const CustomButton: React.FC<CustomButtonProps> = ({
className: classNameFromProps,
disabled,
el: elFromProps = 'link',
href,
label,
newTab,
onClick,
share,
type = 'button',
}) => {
let el = elFromProps

const newTabProps = newTab ? { target: '_blank', rel: 'noopener noreferrer' } : {}

const className = [
classes,
classNameFromProps,
]
.filter(Boolean)
.join(' ')

export default Button;
const content = (
<Button className={cn(`${classes.content}`, '')}>
<span className={cn(`${classes.label}`, '')}>{label}</span>
{share && <ShareIcon />}
</Button>
)

if (onClick || type === 'submit') el = 'button'

if (el === 'link') {
return (
<Link href={href || ''} className={cn(className, '')} {...newTabProps} onClick={onClick} target={`_blank`}>
{content}
</Link>
)
}
const Element: ElementType = el
return (
<Element
href={href}
className={cn(className, '')}
type={type}
{...newTabProps}
onClick={onClick}
disabled={disabled}
>
{content}
</Element>
)
}
16 changes: 16 additions & 0 deletions frontend/src/components/custom/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Card, CardBody, CardFooter, CardHeader, CardProvider, CardSlots, CardVariantProps } from "@nextui-org/react"
export const CustomCard = () => {
return (
<Card>
<CardHeader>

</CardHeader>
<CardBody>

</CardBody>
<CardFooter>

</CardFooter>
</Card>
)
}
24 changes: 24 additions & 0 deletions frontend/src/components/custom/media/Media.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { ElementType, Fragment } from 'react'

import { CustomImage as Image } from './image/Image'
import { Props } from '@/types/frontend/custom-component'
import { Video } from './video/Video'

export const Media: React.FC<Props> = props => {
const { className, resource, htmlElement = 'div' } = props

const isVideo = typeof resource !== 'string' && resource?.mimeType?.includes('video')
const Tag = (htmlElement as ElementType) || Fragment

return (
<Tag
{...(htmlElement !== null
? {
className,
}
: {})}
>
{isVideo ? <Video {...props} /> : <Image {...props} />}
</Tag>
)
}
71 changes: 71 additions & 0 deletions frontend/src/components/custom/media/image/Image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use client'

import React from 'react'

import { Props as MediaProps, StaticImageData } from '@/types/frontend/custom-component'
import { Image } from '@nextui-org/react'
import classes from './index.module.scss'
import { cssVariables } from '@/styles/css/cssVariables'

const { breakpoints } = cssVariables

export const CustomImage: React.FC<MediaProps> = props => {
const {
imgClassName,
onClick,
onLoad: onLoadFromProps,
resource,
fill,
src: srcFromProps,
alt: altFromProps,
} = props

const [isLoading, setIsLoading] = React.useState(true)

let width: number | undefined
let height: number | undefined
let alt = altFromProps
let src: string | StaticImageData = srcFromProps || ''

if (!src && resource && typeof resource !== 'string') {
const {
width: fullWidth,
height: fullHeight,
filename: fullFilename,
alt: altFromResource,
} = resource

width = fullWidth
height = fullHeight
alt = altFromResource

const filename = fullFilename

src = `${import.meta.env.BASE_URL}/assets/images/${filename}`
}

// NOTE: this is used by the browser to determine which image to download at different screen sizes
const sizes = Object.entries(breakpoints)
.map(([, value]) => `(max-width: ${value}px) ${value}px`)
.join(', ')

return (
<Image
className={[isLoading && classes.placeholder, classes.image, imgClassName]
.filter(Boolean)
.join(' ')}
src={typeof src === 'string' ? src : src.src}
alt={alt || ''}
onClick={onClick}
onLoad={() => {
setIsLoading(false)
if (typeof onLoadFromProps === 'function') {
onLoadFromProps()
}
}}
width={!fill ? width : undefined}
height={!fill ? height : undefined}
sizes={sizes}
/>
)
}
7 changes: 7 additions & 0 deletions frontend/src/components/custom/media/image/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.placeholder-color-light {
background-color: rgba(0, 0, 0, 0.05);
}

.placeholder {
background-color: rgb(8, 8, 8)
}
45 changes: 45 additions & 0 deletions frontend/src/components/custom/media/video/Video.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import React, { useEffect, useRef } from 'react'

import { Props as MediaProps } from '@/types/frontend/custom-component';

import classes from './index.module.scss'

export const Video: React.FC<MediaProps> = props => {
const { videoClassName, resource, onClick } = props

const videoRef = useRef<HTMLVideoElement>(null)
// const [showFallback] = useState<boolean>()

useEffect(() => {
const { current: video } = videoRef
if (video) {
video.addEventListener('suspend', () => {
// setShowFallback(true);
// console.warn('Video was suspended, rendering fallback image.')
})
}
}, [])

if (resource && typeof resource !== 'string') {
const { filename } = resource

return (
<video
playsInline
autoPlay
muted
loop
controls={false}
className={[classes.video, videoClassName].filter(Boolean).join(' ')}
onClick={onClick}
ref={videoRef}
>
<source src={`${process.env.NEXT_PUBLIC_SERVER_URL}/media/${filename}`} />
</video>
)
}

return null
}
11 changes: 11 additions & 0 deletions frontend/src/components/custom/media/video/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.video {
max-width: 100%;
width: 100%;
background-color: var(--theme-elevation-50);
}

.cover {
object-fit: cover;
width: 100%;
height: 100%;
}
4 changes: 4 additions & 0 deletions frontend/src/components/effects/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import FadeIn from "./FadeIn";
import { ScaleBackground } from './Scale'

export { FadeIn, ScaleBackground }
13 changes: 13 additions & 0 deletions frontend/src/components/providers/events/Events.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PropsWithChildren } from 'react'
import { Toaster } from 'sonner'

export const Events = ({children}:PropsWithChildren) =>{
return (
<>
<Toaster />
{children}
</>
)
}

export default Events
7 changes: 3 additions & 4 deletions frontend/src/data/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
const config = {
defaultTitle: 'MediGlossary',
url: import.meta.env.VITE_URL as string,
defaultTitle: 'GDSC Farmingdale | Links ',
url: import.meta.env.BASE_URL as string,
defaultDescription:
// eslint-disable-next-line max-len
'This web application is a means to keep up to date with what GDSC FSC is doing, and will include upcoming events, and serve as a central hub for all our domains.',
googleAnalyticsID: 'G-V5F3WWX91X',
googleAnalyticsID: import.meta.env.VITE_MEASUREMENTID as string,

};

Expand Down
15 changes: 15 additions & 0 deletions frontend/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly VITE_APIKEY: string,
readonly VITE_AUTHDOMAIN: string,
readonly VITE_PROJECTID: string,
readonly VITE_STORAGEBUCKET: string,
readonly VITE_MESSAGINGSENDERID: string,
readonly VITE_APPID: string,
readonly VITE_MEASUREMENTID: string
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}
15 changes: 15 additions & 0 deletions frontend/src/firebase/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";

const firebaseConfig = {
apiKey: import.meta.env.VITE_APIKEY as string,
authDomain: import.meta.env.VITE_AUTHDOMAIN as string,
projectId: import.meta.env.VITE_PROJECTID as string,
storageBucket: import.meta.env.VITE_STORAGEBUCKET as string,
messagingSenderId: import.meta.env.VITE_MESSAGINGSENDERID as string,
appId: import.meta.env.VITE_APPID as string,
measurementId: import.meta.env.VITE_MEASUREMENTID as string
};

const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
Loading

0 comments on commit 4fa073f

Please sign in to comment.