Skip to content

Commit

Permalink
Fill about page with content (#104)
Browse files Browse the repository at this point in the history
* add carousel

* Add About page with content and sanitize HTML

* remove use client

* update about page

* Implement upcoming carousel

Co-authored-by: Mathilde Hagl <[email protected]>

* cleanup imports

* adding some design suggestions

* Enhance AboutPage content and update contributor roles for clarity

* Update contributor contribution description for clarity

* update about page text

* add highlighted add custom course phases

* update icons

* small design refinements

* add @rappm as contributor

* fix linter to use prettier

* remove carousel

* implement changes requested by @niclasheun

* @niclasheun fixes 2.0

* update contributor mapping

* update AboutPage dynamically loaded course phases layout and heading spacing

---------

Co-authored-by: Mathilde Hagl <[email protected]>
Co-authored-by: Stefan Niclas Heun <[email protected]>
  • Loading branch information
3 people authored Feb 9, 2025
1 parent d18b876 commit bcf52da
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 19 deletions.
5 changes: 4 additions & 1 deletion clients/core/public/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ window.env = {
KEYCLOAK_HOST: 'http://localhost:8081',
KEYCLOAK_REALM_NAME: 'prompt',
CHAIR_NAME_LONG: 'TUM Research Group for Applied Education Technologies',
CHAIR_NAME_SHORT: 'Applied Education Technologies'
CHAIR_NAME_SHORT: 'Applied Education Technologies',
GITHUB_SHA: 'GITHUB_SHA - Will be here in Production',
GITHUB_REF: '$GITHUB_REF - Will be here in Production',
SERVER_IMAGE_TAG: '$SERVER_IMAGE_TAG - Image Tag',
}
238 changes: 220 additions & 18 deletions clients/core/src/publicPages/legalPages/AboutPage.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,238 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { ArrowLeft, AlertTriangle } from 'lucide-react'
import { useNavigate } from 'react-router-dom'
import {
ArrowLeft,
Bug,
GitPullRequest,
Mail,
FileText,
FileUser,
UserCheck,
Users,
Mic,
Upload,
Plus,
Layers,
} from 'lucide-react'
import { Link, useNavigate } from 'react-router-dom'
import { ContributorList } from './components/ContributorList'
import { env } from '@/env'
import { Separator } from '@/components/ui/separator'

export default function AboutPage() {
const navigate = useNavigate()

const coreFeatures = [
{
icon: Layers,
title: 'Course Configuration',
description:
'Build a course by assembling various course phases to suit your specific teaching needs.',
},
{
icon: FileUser,
title: 'Application Phase',
description:
'Streamline the application process for courses, making it easier for students to apply and for instructors to manage applications.',
},
{
icon: UserCheck,
title: 'Student Management',
description: 'Efficiently manage student information and course participation.',
},
]

const dynamicPhases = [
{
icon: Mic,
title: 'Interview Phase',
description:
'Manage and schedule interviews with applicants as part of the selection process.',
},
{
icon: Upload,
title: 'TUM Matching Export',
description: 'Export data in a format compatible with TUM Matching for seamless integration.',
},
{
icon: Users,
title: 'Team Phase',
description:
'Assign students to teams and projects, and manage project work throughout the course.',
},
]

return (
<div className='container mx-auto py-8 px-4'>
<Card className='w-full max-w-4xl mx-auto'>
<CardHeader className='relative'>
<div className='container mx-auto py-12 px-4'>
<Card className='w-full max-w-6xl mx-auto shadow-lg'>
<CardHeader className='relative pb-8'>
<Button
variant='ghost'
size='icon'
className='absolute left-4 top-4'
className='absolute left-4 top-4 hover:bg-gray-100 transition-colors'
onClick={() => navigate('/')}
aria-label='Go back'
>
<ArrowLeft className='h-4 w-4' />
<ArrowLeft className='h-5 w-5' />
</Button>
<CardTitle className='text-3xl font-bold text-center'>About PROMPT</CardTitle>
<CardDescription className='text-center'>Learn more about our PROMPT</CardDescription>
<CardTitle className='text-4xl font-bold text-center mt-8'>About PROMPT</CardTitle>
<CardDescription className='text-center text-lg mt-2'>
Learn more about our robust course management platform
</CardDescription>
</CardHeader>
<CardContent className='space-y-6'>
<Alert>
<AlertTriangle className='h-4 w-4' />
<AlertTitle>Under Construction</AlertTitle>
<AlertDescription>
This page is still being built. More information will be available soon.
</AlertDescription>
</Alert>
<CardContent className='space-y-12'>
<section>
<h2 className='text-2xl font-semibold mb-4'>What is PROMPT?</h2>
<p className='text-gray-700 leading-relaxed'>
PROMPT (Project-Oriented Modular Platform for Teaching) is a course management tool
specifically designed for project-based university courses. By supporting a wide range
of organizational processes, it reduces the administrative burden typically associated
with such courses and aims to streamline the daily activities of both students and
instructors, enhancing the overall learning experience.
</p>
<p className='text-gray-700 leading-relaxed'>
Originally developed for the iPraktikum at the Technical University of Munich, PROMPT
has been reimagined with a flexible, modular architecture. Each course is built from
independent, reusable components that can be easily extended, giving instructors the
freedom to tailor functionality and structure to their exact teaching needs.
</p>
</section>

<section>
<h2 className='text-2xl font-semibold mb-4'>Get in Touch</h2>
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
{[
{
icon: Bug,
text: 'Report a bug',
link: 'https://github.com/ls1intum/prompt2/issues',
},
{
icon: GitPullRequest,
text: 'Request a feature',
link: 'https://github.com/ls1intum/prompt2/issues',
},
{ icon: Mail, text: 'Contact us', link: 'https://ase.cit.tum.de/impressum/' },
{
icon: FileText,
text: 'Release notes',
link: 'https://github.com/ls1intum/prompt2/releases',
},
].map((item, index) => (
<a
key={index}
href={item.link}
className='flex items-center p-3 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors'
target='_blank'
rel='noopener noreferrer'
>
<item.icon className='h-5 w-5 mr-3 text-blue-600' />
<span className='text-gray-700 hover:text-gray-900'>{item.text}</span>
</a>
))}
</div>
</section>

<Separator />

<section>
<h2 className='text-2xl font-semibold mb-3'>Main Features</h2>
<p className='text-gray-700 leading-relaxed'>
The core features are built-in functionalities essential for course management, while
dynamically loaded phases are additional, customizable components that can be added as
needed.
</p>

<h3 className='text-xl font-semibold mt-8 mb-3'>Core Features</h3>
<h4 className='text-l mb-4 text-secondary-foreground'>
The Core offers a range of essential features designed to enhance the efficiency and
effectiveness of course management.
</h4>
<div className='grid grid-cols-1 md:grid-cols-3 gap-6 mb-8'>
{coreFeatures.map((feature, index) => (
<Card key={index}>
<CardHeader>
<CardTitle className='text-lg font-semibold flex items-center'>
<feature.icon className='h-5 w-5 mr-2 text-blue-600' />
{feature.title}
</CardTitle>
</CardHeader>
<CardContent>
<p className='text-gray-700 text-sm'>{feature.description}</p>
</CardContent>
</Card>
))}
</div>

<h3 className='text-xl font-semibold mb-3'>Dynamically Loaded Course Phases</h3>
<h4 className='text-l mb-4 text-secondary-foreground'>
PROMPT allows instructors to create and manage own independent course phases,
fostering a collaborative and easily extensible platform for project-based learning.
</h4>

<div className='grid grid-cols-1 md:grid-cols-2 md:grid-rows-2 gap-6'>
{dynamicPhases.map((phase, index) => (
<Card key={index}>
<CardHeader>
<CardTitle className='text-lg font-semibold flex items-center'>
<phase.icon className='h-5 w-5 mr-2 text-blue-600' />
{phase.title}
</CardTitle>
</CardHeader>
<CardContent>
<p className='text-gray-700 text-sm'>{phase.description}</p>
</CardContent>
</Card>
))}
<Card className='border border-dashed border-blue-600'>
<CardHeader>
<CardTitle className='text-lg font-semiold flex items-center'>
<Plus className='h-5 w-5 mr-2 text-blue-600' />
Custom Course Phase
</CardTitle>
</CardHeader>
<CardContent>
<p className='text-gray-700 text-sm'>
Easily extend PROMPT with custom phases tailored to your course needs.
</p>
<div className='flex justify-end mt-3'>
<Button variant='outline'>
<Link to='https://ls1intum.github.io/prompt2/' className='btn btn-outline'>
Learn More
</Link>
</Button>
</div>
</CardContent>
</Card>
</div>
</section>

<Separator />

<section>
<h2 className='text-2xl font-semibold mb-6'>Contributors</h2>
<ContributorList />
</section>

<Separator />

<section>
<h2 className='text-2xl font-semibold mb-6'>Release Info</h2>
<ul className='list-disc list-inside text-gray-700'>
<li>
<span className='font-semibold'>Github SHA:</span> {env.GITHUB_SHA}
</li>
<li>
<span className='font-semibold'>Github Ref:</span> {env.GITHUB_REF}
</li>
<li>
<span className='font-semibold'>Image Tag:</span> {env.SERVER_IMAGE_TAG}
</li>
<li>
<span className='font-semibold'>License:</span> MIT
</li>
</ul>
</section>
</CardContent>
</Card>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useEffect, useState } from 'react'
import { Card, CardContent } from '@/components/ui/card'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Contributor, ContributorWithInfo } from '../interfaces/Contributor'
import { contributorMapping } from './ContributorMapping'

export const ContributorList = () => {
const [contributors, setContributors] = useState<Contributor[]>([])
const [vali, setVali] = useState<Contributor>()

useEffect(() => {
fetch('https://api.github.com/repos/ls1intum/prompt2/contributors')
.then((response) => response.json())
.then((data) => setContributors(data))
.catch((error) => console.error('Error fetching contributors:', error))
}, [])

useEffect(() => {
fetch('https://api.github.com/users/airelawaleria')
.then((response) => response.json())
.then((data) => {
if (data) {
setVali({
login: data.login,
avatar_url: data.avatar_url,
html_url: data.html_url,
contributions: 0, // Contributions are not available from this endpoint
type: data.type,
})
}
})
.catch((error) => console.error('Error fetching user:', error))
}, [])

const mappedContributors: ContributorWithInfo[] = [...contributors, vali]
.filter(
(contributor) =>
contributor !== undefined &&
contributorMapping[contributor.login] &&
contributor.type === 'User',
)
.map((contributor) => {
if (contributor === undefined) {
return
}
return {
...contributor,
...contributorMapping[contributor?.login],
}
})
.filter((contributor): contributor is ContributorWithInfo => contributor !== undefined)

return (
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
{mappedContributors
.sort((a, b) => a.position - b.position)
.map((contributor, index) => (
<Card key={index}>
<CardContent className='flex items-center p-4'>
<Avatar className='w-16 h-16 mr-4'>
<AvatarImage src={contributor.avatar_url} alt={contributor.login} />
<AvatarFallback>{contributor.login.slice(0, 2).toUpperCase()}</AvatarFallback>
</Avatar>
<div>
<a
href={contributor.html_url}
target='_blank'
rel='noopener noreferrer'
className='text-blue-600 hover:underline font-semibold'
>
{contributor.name}
</a>
<p className='text-sm text-gray-600 mt-1'>{contributor.contribution}</p>
</div>
</CardContent>
</Card>
))}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const contributorMapping: {
[username: string]: {
name: string
contribution: string
position: number
}
} = {
niclasheun: {
name: 'Niclas Heun',
contribution: 'Lead Developer & Architect of PROMPT 2.0',
position: 2,
},
Mtze: { name: 'Matthias Linhuber', contribution: 'Project Manager', position: 1 },
mathildeshagl: {
name: 'Mathilde Hagl',
contribution: 'Templating and Task Management',
position: 4,
},
airelawaleria: {
name: 'Valeryia Andraichuk',
contribution: 'Creator of PROMPT - the concept on which PROMPT 2.0 is based',
position: 3,
},
rappm: { name: 'Maximilian Rapp', contribution: 'Grading', position: 5 },
}
13 changes: 13 additions & 0 deletions clients/core/src/publicPages/legalPages/interfaces/Contributor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface Contributor {
login: string
avatar_url: string
html_url: string
contributions: number
type: string
}

export interface ContributorWithInfo extends Contributor {
name: string
contribution: string
position: number
}
3 changes: 3 additions & 0 deletions clients/shared_library/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ type EnvType = {
KEYCLOAK_REALM_NAME: string
CHAIR_NAME_LONG: string
CHAIR_NAME_SHORT: string
GITHUB_SHA: string
GITHUB_REF: string
SERVER_IMAGE_TAG: string
}
export const env: EnvType = { ...window.env }

0 comments on commit bcf52da

Please sign in to comment.